VirtualBox

source: kBuild/trunk/src/kash/miscbltin.c@ 1214

Last change on this file since 1214 was 1214, checked in by bird, 17 years ago

some more cleanup.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette