Rev 2714 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2714 | Rev 3241 | ||
---|---|---|---|
1 | /* $NetBSD: miscbltin.c,v 1.29 2001/01/04 15:39:51 lukem Exp $ */ |
1 | /* $NetBSD: miscbltin.c,v 1.29 2001/01/04 15:39:51 lukem Exp $ */ |
2 | 2 | ||
3 | /*- |
3 | /*- |
4 | * Copyright (c) 1991, 1993 |
4 | * Copyright (c) 1991, 1993 |
5 | * The Regents of the University of California. All rights reserved. |
5 | * The Regents of the University of California. All rights reserved. |
6 | * |
6 | * |
7 | * This code is derived from software contributed to Berkeley by |
7 | * This code is derived from software contributed to Berkeley by |
8 | * Kenneth Almquist. |
8 | * Kenneth Almquist. |
9 | * |
9 | * |
10 | * Redistribution and use in source and binary forms, with or without |
10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions |
11 | * modification, are permitted provided that the following conditions |
12 | * are met: |
12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright |
13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. |
14 | * notice, this list of conditions and the following disclaimer. |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in the |
16 | * notice, this list of conditions and the following disclaimer in the |
17 | * documentation and/or other materials provided with the distribution. |
17 | * documentation and/or other materials provided with the distribution. |
18 | * 3. All advertising materials mentioning features or use of this software |
18 | * 3. All advertising materials mentioning features or use of this software |
19 | * must display the following acknowledgement: |
19 | * must display the following acknowledgement: |
20 | * This product includes software developed by the University of |
20 | * This product includes software developed by the University of |
21 | * California, Berkeley and its contributors. |
21 | * California, Berkeley and its contributors. |
22 | * 4. Neither the name of the University nor the names of its contributors |
22 | * 4. Neither the name of the University nor the names of its contributors |
23 | * may be used to endorse or promote products derived from this software |
23 | * may be used to endorse or promote products derived from this software |
24 | * without specific prior written permission. |
24 | * without specific prior written permission. |
25 | * |
25 | * |
26 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
26 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
34 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
36 | * SUCH DAMAGE. |
36 | * SUCH DAMAGE. |
37 | */ |
37 | */ |
38 | 38 | ||
39 | #include <sys/cdefs.h> |
39 | #include <sys/cdefs.h> |
40 | #ifndef lint |
40 | #ifndef lint |
41 | #if 0 |
41 | #if 0 |
42 | static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95"; |
42 | static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95"; |
43 | #else |
43 | #else |
44 | __RCSID("$NetBSD: miscbltin.c,v 1.29 2001/01/04 15:39:51 lukem Exp $"); |
44 | __RCSID("$NetBSD: miscbltin.c,v 1.29 2001/01/04 15:39:51 lukem Exp $"); |
45 | #endif |
45 | #endif |
46 | #endif /* not lint */ |
46 | #endif /* not lint */ |
47 | 47 | ||
48 | /* |
48 | /* |
49 | * Miscelaneous builtins. |
49 | * Miscelaneous builtins. |
50 | */ |
50 | */ |
51 | 51 | ||
52 | #include <sys/types.h> /* quad_t */ |
52 | #include <sys/types.h> /* quad_t */ |
53 | #include <sys/param.h> /* BSD4_4 */ |
53 | #include <sys/param.h> /* BSD4_4 */ |
54 | #include <sys/stat.h> |
54 | #include <sys/stat.h> |
55 | #include <sys/time.h> |
55 | #include <sys/time.h> |
56 | #include <sys/resource.h> |
56 | #include <sys/resource.h> |
57 | #include <unistd.h> |
57 | #include <unistd.h> |
58 | #include <stdlib.h> |
58 | #include <stdlib.h> |
59 | #include <ctype.h> |
59 | #include <ctype.h> |
60 | #include <errno.h> |
60 | #include <errno.h> |
61 | 61 | ||
62 | #include "shell.h" |
62 | #include "shell.h" |
63 | #include "options.h" |
63 | #include "options.h" |
64 | #include "var.h" |
64 | #include "var.h" |
65 | #include "output.h" |
65 | #include "output.h" |
66 | #include "memalloc.h" |
66 | #include "memalloc.h" |
67 | #include "error.h" |
67 | #include "error.h" |
68 | #include "miscbltin.h" |
68 | #include "miscbltin.h" |
69 | #include "mystring.h" |
69 | #include "mystring.h" |
70 | 70 | ||
71 | #undef rflag |
71 | #undef rflag |
72 | 72 | ||
73 | #ifdef __GLIBC__ |
73 | #ifdef __GLIBC__ |
74 | mode_t getmode(const void *, mode_t); |
74 | mode_t getmode(const void *, mode_t); |
75 | void *setmode(const char *); |
75 | void *setmode(const char *); |
76 | 76 | ||
77 | #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1 |
77 | #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1 |
78 | typedef enum __rlimit_resource rlim_t; |
78 | typedef enum __rlimit_resource rlim_t; |
79 | #endif |
79 | #endif |
80 | #endif |
80 | #endif |
81 | 81 | ||
82 | extern char **argptr; /* argument list for builtin command */ |
82 | extern char **argptr; /* argument list for builtin command */ |
83 | 83 | ||
84 | 84 | ||
85 | /* |
85 | /* |
86 | * The read builtin. The -e option causes backslashes to escape the |
86 | * The read builtin. The -e option causes backslashes to escape the |
87 | * following character. |
87 | * following character. |
88 | * |
88 | * |
89 | * This uses unbuffered input, which may be avoidable in some cases. |
89 | * This uses unbuffered input, which may be avoidable in some cases. |
90 | */ |
90 | */ |
91 | 91 | ||
92 | int |
92 | int |
93 | readcmd(argc, argv) |
93 | readcmd(argc, argv) |
94 | int argc; |
94 | int argc; |
95 | char **argv; |
95 | char **argv; |
96 | { |
96 | { |
97 | char **ap; |
97 | char **ap; |
98 | int backslash; |
98 | int backslash; |
99 | char c; |
99 | char c; |
100 | int rflag; |
100 | int rflag; |
101 | char *prompt; |
101 | char *prompt; |
102 | char *ifs; |
102 | char *ifs; |
103 | char *p; |
103 | char *p; |
104 | int startword; |
104 | int startword; |
105 | int status; |
105 | int status; |
106 | int i; |
106 | int i; |
107 | 107 | ||
108 | rflag = 0; |
108 | rflag = 0; |
109 | prompt = NULL; |
109 | prompt = NULL; |
110 | while ((i = nextopt("p:r")) != '\0') { |
110 | while ((i = nextopt("p:r")) != '\0') { |
111 | if (i == 'p') |
111 | if (i == 'p') |
112 | prompt = optarg; |
112 | prompt = optarg; |
113 | else |
113 | else |
114 | rflag = 1; |
114 | rflag = 1; |
115 | } |
115 | } |
116 | if (prompt && isatty(0)) { |
116 | if (prompt && isatty(0)) { |
117 | out2str(prompt); |
117 | out2str(prompt); |
118 | flushall(); |
118 | flushall(); |
119 | } |
119 | } |
120 | if (*(ap = argptr) == NULL) |
120 | if (*(ap = argptr) == NULL) |
121 | error("arg count"); |
121 | error("arg count"); |
122 | if ((ifs = bltinlookup("IFS", 1)) == NULL) |
122 | if ((ifs = bltinlookup("IFS", 1)) == NULL) |
123 | ifs = nullstr; |
123 | ifs = nullstr; |
124 | status = 0; |
124 | status = 0; |
125 | startword = 1; |
125 | startword = 1; |
126 | backslash = 0; |
126 | backslash = 0; |
127 | STARTSTACKSTR(p); |
127 | STARTSTACKSTR(p); |
128 | for (;;) { |
128 | for (;;) { |
129 | if (read(0, &c, 1) != 1) { |
129 | if (read(0, &c, 1) != 1) { |
130 | status = 1; |
130 | status = 1; |
131 | break; |
131 | break; |
132 | } |
132 | } |
133 | if (c == '\0') |
133 | if (c == '\0') |
134 | continue; |
134 | continue; |
135 | if (backslash) { |
135 | if (backslash) { |
136 | backslash = 0; |
136 | backslash = 0; |
137 | if (c != '\n') |
137 | if (c != '\n') |
138 | STPUTC(c, p); |
138 | STPUTC(c, p); |
139 | continue; |
139 | continue; |
140 | } |
140 | } |
141 | if (!rflag && c == '\\') { |
141 | if (!rflag && c == '\\') { |
142 | backslash++; |
142 | backslash++; |
143 | continue; |
143 | continue; |
144 | } |
144 | } |
145 | if (c == '\n') |
145 | if (c == '\n') |
146 | break; |
146 | break; |
147 | if (startword && *ifs == ' ' && strchr(ifs, c)) { |
147 | if (startword && *ifs == ' ' && strchr(ifs, c)) { |
148 | continue; |
148 | continue; |
149 | } |
149 | } |
150 | startword = 0; |
150 | startword = 0; |
151 | if (backslash && c == '\\') { |
151 | if (backslash && c == '\\') { |
152 | if (read(0, &c, 1) != 1) { |
152 | if (read(0, &c, 1) != 1) { |
153 | status = 1; |
153 | status = 1; |
154 | break; |
154 | break; |
155 | } |
155 | } |
156 | STPUTC(c, p); |
156 | STPUTC(c, p); |
157 | } else if (ap[1] != NULL && strchr(ifs, c) != NULL) { |
157 | } else if (ap[1] != NULL && strchr(ifs, c) != NULL) { |
158 | STACKSTRNUL(p); |
158 | STACKSTRNUL(p); |
159 | setvar(*ap, stackblock(), 0); |
159 | setvar(*ap, stackblock(), 0); |
160 | ap++; |
160 | ap++; |
161 | startword = 1; |
161 | startword = 1; |
162 | STARTSTACKSTR(p); |
162 | STARTSTACKSTR(p); |
163 | } else { |
163 | } else { |
164 | STPUTC(c, p); |
164 | STPUTC(c, p); |
165 | } |
165 | } |
166 | } |
166 | } |
167 | STACKSTRNUL(p); |
167 | STACKSTRNUL(p); |
168 | /* Remove trailing blanks */ |
168 | /* Remove trailing blanks */ |
169 | while (stackblock() <= --p && strchr(ifs, *p) != NULL) |
169 | while (stackblock() <= --p && strchr(ifs, *p) != NULL) |
170 | *p = '\0'; |
170 | *p = '\0'; |
171 | setvar(*ap, stackblock(), 0); |
171 | setvar(*ap, stackblock(), 0); |
172 | while (*++ap != NULL) |
172 | while (*++ap != NULL) |
173 | setvar(*ap, nullstr, 0); |
173 | setvar(*ap, nullstr, 0); |
174 | return status; |
174 | return status; |
175 | } |
175 | } |
176 | 176 | ||
177 | 177 | ||
178 | 178 | ||
179 | int |
179 | int |
180 | umaskcmd(argc, argv) |
180 | umaskcmd(argc, argv) |
181 | int argc; |
181 | int argc; |
182 | char **argv; |
182 | char **argv; |
183 | { |
183 | { |
184 | char *ap; |
184 | char *ap; |
185 | int mask; |
185 | int mask; |
186 | int i; |
186 | int i; |
187 | int symbolic_mode = 0; |
187 | int symbolic_mode = 0; |
188 | 188 | ||
189 | while ((i = nextopt("S")) != '\0') { |
189 | while ((i = nextopt("S")) != '\0') { |
190 | symbolic_mode = 1; |
190 | symbolic_mode = 1; |
191 | } |
191 | } |
192 | 192 | ||
193 | INTOFF; |
193 | INTOFF; |
194 | mask = umask(0); |
194 | mask = umask(0); |
195 | umask(mask); |
195 | umask(mask); |
196 | INTON; |
196 | INTON; |
197 | 197 | ||
198 | if ((ap = *argptr) == NULL) { |
198 | if ((ap = *argptr) == NULL) { |
199 | if (symbolic_mode) { |
199 | if (symbolic_mode) { |
200 | char u[4], g[4], o[4]; |
200 | char u[4], g[4], o[4]; |
201 | 201 | ||
202 | i = 0; |
202 | i = 0; |
203 | if ((mask & S_IRUSR) == 0) |
203 | if ((mask & S_IRUSR) == 0) |
204 | u[i++] = 'r'; |
204 | u[i++] = 'r'; |
205 | if ((mask & S_IWUSR) == 0) |
205 | if ((mask & S_IWUSR) == 0) |
206 | u[i++] = 'w'; |
206 | u[i++] = 'w'; |
207 | if ((mask & S_IXUSR) == 0) |
207 | if ((mask & S_IXUSR) == 0) |
208 | u[i++] = 'x'; |
208 | u[i++] = 'x'; |
209 | u[i] = '\0'; |
209 | u[i] = '\0'; |
210 | 210 | ||
211 | i = 0; |
211 | i = 0; |
212 | if ((mask & S_IRGRP) == 0) |
212 | if ((mask & S_IRGRP) == 0) |
213 | g[i++] = 'r'; |
213 | g[i++] = 'r'; |
214 | if ((mask & S_IWGRP) == 0) |
214 | if ((mask & S_IWGRP) == 0) |
215 | g[i++] = 'w'; |
215 | g[i++] = 'w'; |
216 | if ((mask & S_IXGRP) == 0) |
216 | if ((mask & S_IXGRP) == 0) |
217 | g[i++] = 'x'; |
217 | g[i++] = 'x'; |
218 | g[i] = '\0'; |
218 | g[i] = '\0'; |
219 | 219 | ||
220 | i = 0; |
220 | i = 0; |
221 | if ((mask & S_IROTH) == 0) |
221 | if ((mask & S_IROTH) == 0) |
222 | o[i++] = 'r'; |
222 | o[i++] = 'r'; |
223 | if ((mask & S_IWOTH) == 0) |
223 | if ((mask & S_IWOTH) == 0) |
224 | o[i++] = 'w'; |
224 | o[i++] = 'w'; |
225 | if ((mask & S_IXOTH) == 0) |
225 | if ((mask & S_IXOTH) == 0) |
226 | o[i++] = 'x'; |
226 | o[i++] = 'x'; |
227 | o[i] = '\0'; |
227 | o[i] = '\0'; |
228 | 228 | ||
229 | out1fmt("u=%s,g=%s,o=%s\n", u, g, o); |
229 | out1fmt("u=%s,g=%s,o=%s\n", u, g, o); |
230 | } else { |
230 | } else { |
231 | out1fmt("%.4o\n", mask); |
231 | out1fmt("%.4o\n", mask); |
232 | } |
232 | } |
233 | } else { |
233 | } else { |
234 | if (isdigit((unsigned char)*ap)) { |
234 | if (isdigit((unsigned char)*ap)) { |
235 | mask = 0; |
235 | mask = 0; |
236 | do { |
236 | do { |
237 | if (*ap >= '8' || *ap < '0') |
237 | if (*ap >= '8' || *ap < '0') |
238 | error("Illegal number: %s", argv[1]); |
238 | error("Illegal number: %s", argv[1]); |
239 | mask = (mask << 3) + (*ap - '0'); |
239 | mask = (mask << 3) + (*ap - '0'); |
240 | } while (*++ap != '\0'); |
240 | } while (*++ap != '\0'); |
241 | umask(mask); |
241 | umask(mask); |
242 | } else { |
242 | } else { |
243 | void *set; |
243 | void *set; |
244 | 244 | ||
245 | INTOFF; |
245 | INTOFF; |
246 | if ((set = setmode(ap)) != 0) { |
246 | if ((set = setmode(ap)) != 0) { |
247 | mask = getmode(set, ~mask & 0777); |
247 | mask = getmode(set, ~mask & 0777); |
248 | ckfree(set); |
248 | ckfree(set); |
249 | } |
249 | } |
250 | INTON; |
250 | INTON; |
251 | if (!set) |
251 | if (!set) |
252 | error("Illegal mode: %s", ap); |
252 | error("Illegal mode: %s", ap); |
253 | 253 | ||
254 | umask(~mask & 0777); |
254 | umask(~mask & 0777); |
255 | } |
255 | } |
256 | } |
256 | } |
257 | return 0; |
257 | return 0; |
258 | } |
258 | } |
259 | 259 | ||
260 | /* |
260 | /* |
261 | * ulimit builtin |
261 | * ulimit builtin |
262 | * |
262 | * |
263 | * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and |
263 | * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and |
264 | * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with |
264 | * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with |
265 | * ash by J.T. Conklin. |
265 | * ash by J.T. Conklin. |
266 | * |
266 | * |
267 | * Public domain. |
267 | * Public domain. |
268 | */ |
268 | */ |
269 | 269 | ||
270 | struct limits { |
270 | struct limits { |
271 | const char *name; |
271 | const char *name; |
272 | int cmd; |
272 | int cmd; |
273 | int factor; /* multiply by to get rlim_{cur,max} values */ |
273 | int factor; /* multiply by to get rlim_{cur,max} values */ |
274 | char option; |
274 | char option; |
275 | }; |
275 | }; |
276 | 276 | ||
277 | static const struct limits limits[] = { |
277 | static const struct limits limits[] = { |
278 | #ifdef RLIMIT_CPU |
278 | #ifdef RLIMIT_CPU |
279 | { "time(seconds)", RLIMIT_CPU, 1, 't' }, |
279 | { "time(seconds)", RLIMIT_CPU, 1, 't' }, |
280 | #endif |
280 | #endif |
281 | #ifdef RLIMIT_FSIZE |
281 | #ifdef RLIMIT_FSIZE |
282 | { "file(blocks)", RLIMIT_FSIZE, 512, 'f' }, |
282 | { "file(blocks)", RLIMIT_FSIZE, 512, 'f' }, |
283 | #endif |
283 | #endif |
284 | #ifdef RLIMIT_DATA |
284 | #ifdef RLIMIT_DATA |
285 | { "data(kbytes)", RLIMIT_DATA, 1024, 'd' }, |
285 | { "data(kbytes)", RLIMIT_DATA, 1024, 'd' }, |
286 | #endif |
286 | #endif |
287 | #ifdef RLIMIT_STACK |
287 | #ifdef RLIMIT_STACK |
288 | { "stack(kbytes)", RLIMIT_STACK, 1024, 's' }, |
288 | { "stack(kbytes)", RLIMIT_STACK, 1024, 's' }, |
289 | #endif |
289 | #endif |
290 | #ifdef RLIMIT_CORE |
290 | #ifdef RLIMIT_CORE |
291 | { "coredump(blocks)", RLIMIT_CORE, 512, 'c' }, |
291 | { "coredump(blocks)", RLIMIT_CORE, 512, 'c' }, |
292 | #endif |
292 | #endif |
293 | #ifdef RLIMIT_RSS |
293 | #ifdef RLIMIT_RSS |
294 | { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' }, |
294 | { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' }, |
295 | #endif |
295 | #endif |
296 | #ifdef RLIMIT_MEMLOCK |
296 | #ifdef RLIMIT_MEMLOCK |
297 | { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' }, |
297 | { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' }, |
298 | #endif |
298 | #endif |
299 | #ifdef RLIMIT_NPROC |
299 | #ifdef RLIMIT_NPROC |
300 | { "process(processes)", RLIMIT_NPROC, 1, 'p' }, |
300 | { "process(processes)", RLIMIT_NPROC, 1, 'p' }, |
301 | #endif |
301 | #endif |
302 | #ifdef RLIMIT_NOFILE |
302 | #ifdef RLIMIT_NOFILE |
303 | { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' }, |
303 | { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' }, |
304 | #endif |
304 | #endif |
305 | #ifdef RLIMIT_VMEM |
305 | #ifdef RLIMIT_VMEM |
306 | { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' }, |
306 | { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' }, |
307 | #endif |
307 | #endif |
308 | #ifdef RLIMIT_SWAP |
308 | #ifdef RLIMIT_SWAP |
309 | { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' }, |
309 | { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' }, |
310 | #endif |
310 | #endif |
311 | { (char *) 0, 0, 0, '\0' } |
311 | { (char *) 0, 0, 0, '\0' } |
312 | }; |
312 | }; |
313 | 313 | ||
314 | int |
314 | int |
315 | ulimitcmd(argc, argv) |
315 | ulimitcmd(argc, argv) |
316 | int argc; |
316 | int argc; |
317 | char **argv; |
317 | char **argv; |
318 | { |
318 | { |
319 | int c; |
319 | int c; |
320 | rlim_t val = 0; |
320 | rlim_t val = 0; |
321 | enum { SOFT = 0x1, HARD = 0x2 } |
321 | enum { SOFT = 0x1, HARD = 0x2 } |
322 | how = SOFT | HARD; |
322 | how = SOFT | HARD; |
323 | const struct limits *l; |
323 | const struct limits *l; |
324 | int set, all = 0; |
324 | int set, all = 0; |
325 | int optc, what; |
325 | int optc, what; |
326 | struct rlimit limit; |
326 | struct rlimit limit; |
327 | 327 | ||
328 | what = 'f'; |
328 | what = 'f'; |
329 | while ((optc = nextopt("HSatfdsmcnpl")) != '\0') |
329 | while ((optc = nextopt("HSatfdsmcnpl")) != '\0') |
330 | switch (optc) { |
330 | switch (optc) { |
331 | case 'H': |
331 | case 'H': |
332 | how = HARD; |
332 | how = HARD; |
333 | break; |
333 | break; |
334 | case 'S': |
334 | case 'S': |
335 | how = SOFT; |
335 | how = SOFT; |
336 | break; |
336 | break; |
337 | case 'a': |
337 | case 'a': |
338 | all = 1; |
338 | all = 1; |
339 | break; |
339 | break; |
340 | default: |
340 | default: |
341 | what = optc; |
341 | what = optc; |
342 | } |
342 | } |
343 | 343 | ||
344 | for (l = limits; l->name && l->option != what; l++) |
344 | for (l = limits; l->name && l->option != what; l++) |
345 | ; |
345 | ; |
346 | if (!l->name) |
346 | if (!l->name) |
347 | error("internal error (%c)", what); |
347 | error("internal error (%c)", what); |
348 | 348 | ||
349 | set = *argptr ? 1 : 0; |
349 | set = *argptr ? 1 : 0; |
350 | if (set) { |
350 | if (set) { |
351 | char *p = *argptr; |
351 | char *p = *argptr; |
352 | 352 | ||
353 | if (all || argptr[1]) |
353 | if (all || argptr[1]) |
354 | error("too many arguments"); |
354 | error("too many arguments"); |
355 | if (strcmp(p, "unlimited") == 0) |
355 | if (strcmp(p, "unlimited") == 0) |
356 | val = RLIM_INFINITY; |
356 | val = RLIM_INFINITY; |
357 | else { |
357 | else { |
358 | val = (rlim_t) 0; |
358 | val = (rlim_t) 0; |
359 | 359 | ||
360 | while ((c = *p++) >= '0' && c <= '9') |
360 | while ((c = *p++) >= '0' && c <= '9') |
361 | { |
361 | { |
362 | val = (val * 10) + (long)(c - '0'); |
362 | val = (val * 10) + (long)(c - '0'); |
363 | if (val < (rlim_t) 0) |
363 | if (val < (rlim_t) 0) |
364 | break; |
364 | break; |
365 | } |
365 | } |
366 | if (c) |
366 | if (c) |
367 | error("bad number"); |
367 | error("bad number"); |
368 | val *= l->factor; |
368 | val *= l->factor; |
369 | } |
369 | } |
370 | } |
370 | } |
371 | if (all) { |
371 | if (all) { |
372 | for (l = limits; l->name; l++) { |
372 | for (l = limits; l->name; l++) { |
373 | getrlimit(l->cmd, &limit); |
373 | getrlimit(l->cmd, &limit); |
374 | if (how & SOFT) |
374 | if (how & SOFT) |
375 | val = limit.rlim_cur; |
375 | val = limit.rlim_cur; |
376 | else if (how & HARD) |
376 | else if (how & HARD) |
377 | val = limit.rlim_max; |
377 | val = limit.rlim_max; |
378 | 378 | ||
379 | out1fmt("%-20s ", l->name); |
379 | out1fmt("%-20s ", l->name); |
380 | if (val == RLIM_INFINITY) |
380 | if (val == RLIM_INFINITY) |
381 | out1fmt("unlimited\n"); |
381 | out1fmt("unlimited\n"); |
382 | else |
382 | else |
383 | { |
383 | { |
384 | val /= l->factor; |
384 | val /= l->factor; |
385 | #ifdef BSD4_4 |
385 | #ifdef BSD4_4 |
386 | out1fmt("%lld\n", (long long) val); |
386 | out1fmt("%lld\n", (long long) val); |
387 | #else |
387 | #else |
388 | out1fmt("%ld\n", (long) val); |
388 | out1fmt("%ld\n", (long) val); |
389 | #endif |
389 | #endif |
390 | } |
390 | } |
391 | } |
391 | } |
392 | return 0; |
392 | return 0; |
393 | } |
393 | } |
394 | 394 | ||
395 | getrlimit(l->cmd, &limit); |
395 | getrlimit(l->cmd, &limit); |
396 | if (set) { |
396 | if (set) { |
397 | if (how & HARD) |
397 | if (how & HARD) |
398 | limit.rlim_max = val; |
398 | limit.rlim_max = val; |
399 | if (how & SOFT) |
399 | if (how & SOFT) |
400 | limit.rlim_cur = val; |
400 | limit.rlim_cur = val; |
401 | if (setrlimit(l->cmd, &limit) < 0) |
401 | if (setrlimit(l->cmd, &limit) < 0) |
402 | error("error setting limit (%s)", strerror(errno)); |
402 | error("error setting limit (%s)", strerror(errno)); |
403 | } else { |
403 | } else { |
404 | if (how & SOFT) |
404 | if (how & SOFT) |
405 | val = limit.rlim_cur; |
405 | val = limit.rlim_cur; |
406 | else if (how & HARD) |
406 | else if (how & HARD) |
407 | val = limit.rlim_max; |
407 | val = limit.rlim_max; |
408 | 408 | ||
409 | if (val == RLIM_INFINITY) |
409 | if (val == RLIM_INFINITY) |
410 | out1fmt("unlimited\n"); |
410 | out1fmt("unlimited\n"); |
411 | else |
411 | else |
412 | { |
412 | { |
413 | val /= l->factor; |
413 | val /= l->factor; |
414 | #ifdef BSD4_4 |
414 | #ifdef BSD4_4 |
415 | out1fmt("%lld\n", (long long) val); |
415 | out1fmt("%lld\n", (long long) val); |
416 | #else |
416 | #else |
417 | out1fmt("%ld\n", (long) val); |
417 | out1fmt("%ld\n", (long) val); |
418 | #endif |
418 | #endif |
419 | } |
419 | } |
420 | } |
420 | } |
421 | return 0; |
421 | return 0; |
422 | } |
422 | } |
423 | 423 |