2
* Copyright (c) 1991, 1993
3
* The Regents of the University of California. All rights reserved.
4
* Copyright (c) 1997-2005
5
* Herbert Xu <herbert@gondor.apana.org.au>. All rights reserved.
7
* This code is derived from software contributed to Berkeley by
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
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.
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
36
* Miscelaneous builtins.
39
#include <sys/types.h> /* quad_t */
40
#include <sys/param.h> /* BSD4_4 */
43
#include <sys/resource.h>
55
#include "miscbltin.h"
64
* The read builtin. The -e option causes backslashes to escape the
65
* following character.
67
* This uses unbuffered input, which may be avoidable in some cases.
71
readcmd(int argc, char **argv)
86
while ((i = nextopt("p:r")) != '\0') {
92
if (prompt && isatty(0)) {
98
if (*(ap = argptr) == NULL)
99
sh_error("arg count");
100
if ((ifs = bltinlookup("IFS")) == NULL)
107
if (read(0, &c, 1) != 1) {
119
if (!rflag && c == '\\') {
125
if (startword && *ifs == ' ' && strchr(ifs, c)) {
129
if (ap[1] != NULL && strchr(ifs, c) != NULL) {
131
setvar(*ap, stackblock(), 0);
141
/* Remove trailing blanks */
142
while ((char *)stackblock() <= --p && strchr(ifs, *p) != NULL)
144
setvar(*ap, stackblock(), 0);
145
while (*++ap != NULL)
146
setvar(*ap, nullstr, 0);
155
* This code was ripped from pdksh 5.2.14 and hacked for use with
156
* dash by Herbert Xu.
162
umaskcmd(int argc, char **argv)
167
int symbolic_mode = 0;
169
while ((i = nextopt("S")) != '\0') {
178
if ((ap = *argptr) == NULL) {
185
for (i = 0; i < 3; i++) {
188
for (j = 0; j < 3; j++)
189
if (mask & (1 << (8 - (3*i + j))))
194
out1fmt("%s\n", buf);
196
out1fmt("%.4o\n", mask);
204
if (*ap >= '8' || *ap < '0')
205
sh_error(illnum, *argptr);
206
new_mask = (new_mask << 3) + (*ap - '0');
207
} while (*++ap != '\0');
209
int positions, new_val;
216
while (*ap && strchr("augo", *ap))
218
case 'a': positions |= 0111; break;
219
case 'u': positions |= 0100; break;
220
case 'g': positions |= 0010; break;
221
case 'o': positions |= 0001; break;
224
positions = 0111; /* default is a */
225
if (!strchr("=+-", op = *ap))
229
while (*ap && strchr("rwxugoXs", *ap))
231
case 'r': new_val |= 04; break;
232
case 'w': new_val |= 02; break;
233
case 'x': new_val |= 01; break;
234
case 'u': new_val |= mask >> 6;
236
case 'g': new_val |= mask >> 3;
238
case 'o': new_val |= mask >> 0;
240
case 'X': if (mask & 0111)
243
case 's': /* ignored */
246
new_val = (new_val & 07) * positions;
249
new_mask &= ~new_val;
253
| (new_mask & ~(positions * 07));
261
} else if (!strchr("=+-", *ap))
265
sh_error("Illegal mode: %s", *argptr);
268
new_mask = ~new_mask;
275
#ifdef HAVE_GETRLIMIT
279
* This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
280
* Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
281
* ash by J.T. Conklin.
289
int factor; /* multiply by to get rlim_{cur,max} values */
293
static const struct limits limits[] = {
295
{ "time(seconds)", RLIMIT_CPU, 1, 't' },
298
{ "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
301
{ "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
304
{ "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
307
{ "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
310
{ "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
312
#ifdef RLIMIT_MEMLOCK
313
{ "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
316
{ "process", RLIMIT_NPROC, 1, 'p' },
319
{ "nofiles", RLIMIT_NOFILE, 1, 'n' },
322
{ "vmemory(kbytes)", RLIMIT_AS, 1024, 'v' },
325
{ "locks", RLIMIT_LOCKS, 1, 'w' },
327
{ (char *) 0, 0, 0, '\0' }
330
enum limtype { SOFT = 0x1, HARD = 0x2 };
332
static void printlim(enum limtype how, const struct rlimit *limit,
333
const struct limits *l)
337
val = limit->rlim_max;
339
val = limit->rlim_cur;
341
if (val == RLIM_INFINITY)
342
out1fmt("unlimited\n");
345
out1fmt("%jd\n", (intmax_t) val);
350
ulimitcmd(int argc, char **argv)
354
enum limtype how = SOFT | HARD;
355
const struct limits *l;
361
while ((optc = nextopt("HSa"
380
#ifdef RLIMIT_MEMLOCK
410
for (l = limits; l->option != what; l++)
413
set = *argptr ? 1 : 0;
417
if (all || argptr[1])
418
sh_error("too many arguments");
419
if (strcmp(p, "unlimited") == 0)
424
while ((c = *p++) >= '0' && c <= '9')
426
val = (val * 10) + (long)(c - '0');
427
if (val < (rlim_t) 0)
431
sh_error("bad number");
436
for (l = limits; l->name; l++) {
437
getrlimit(l->cmd, &limit);
438
out1fmt("%-20s ", l->name);
439
printlim(how, &limit, l);
444
getrlimit(l->cmd, &limit);
447
limit.rlim_max = val;
449
limit.rlim_cur = val;
450
if (setrlimit(l->cmd, &limit) < 0)
451
sh_error("error setting limit (%s)", strerror(errno));
453
printlim(how, &limit, l);