summaryrefslogtreecommitdiffstats
path: root/bin/sh/miscbltin.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/sh/miscbltin.c')
-rw-r--r--bin/sh/miscbltin.c424
1 files changed, 216 insertions, 208 deletions
diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c
index 414ed81..ca37fc1 100644
--- a/bin/sh/miscbltin.c
+++ b/bin/sh/miscbltin.c
@@ -4,7 +4,6 @@
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
- * The ulimit() builtin has been contributed by Joerg Wunsch.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -34,17 +33,24 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: miscbltin.c,v 1.3 1995/10/19 18:42:10 joerg Exp $
+ * $Id: miscbltin.c,v 1.4 1995/10/21 00:47:30 joerg Exp $
*/
#ifndef lint
-static char sccsid[] = "@(#)miscbltin.c 8.2 (Berkeley) 4/16/94";
+static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95";
#endif /* not lint */
/*
* Miscelaneous builtins.
*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <ctype.h>
+
#include "shell.h"
#include "options.h"
#include "var.h"
@@ -53,18 +59,6 @@ static char sccsid[] = "@(#)miscbltin.c 8.2 (Berkeley) 4/16/94";
#include "error.h"
#include "mystring.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#if BSD
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif
-
#undef eflag
extern char **argptr; /* argument list for builtin command */
@@ -77,7 +71,11 @@ extern char **argptr; /* argument list for builtin command */
* This uses unbuffered input, which may be avoidable in some cases.
*/
-readcmd(argc, argv) char **argv; {
+int
+readcmd(argc, argv)
+ int argc;
+ char **argv;
+{
char **ap;
int backslash;
char c;
@@ -157,225 +155,235 @@ readcmd(argc, argv) char **argv; {
-umaskcmd(argc, argv) char **argv; {
+int
+umaskcmd(argc, argv)
+ int argc;
+ char **argv;
+{
+ char *ap;
int mask;
- char *p;
int i;
+ int symbolic_mode = 0;
+
+ while ((i = nextopt("S")) != '\0') {
+ symbolic_mode = 1;
+ }
+
+ INTOFF;
+ mask = umask(0);
+ umask(mask);
+ INTON;
+
+ if ((ap = *argptr) == NULL) {
+ if (symbolic_mode) {
+ char u[4], g[4], o[4];
- if ((p = argv[1]) == NULL) {
- INTOFF;
- mask = umask(0);
- umask(mask);
- INTON;
- out1fmt("%.4o\n", mask); /* %#o might be better */
+ i = 0;
+ if ((mask & S_IRUSR) == 0)
+ u[i++] = 'r';
+ if ((mask & S_IWUSR) == 0)
+ u[i++] = 'w';
+ if ((mask & S_IXUSR) == 0)
+ u[i++] = 'x';
+ u[i] = '\0';
+
+ i = 0;
+ if ((mask & S_IRGRP) == 0)
+ g[i++] = 'r';
+ if ((mask & S_IWGRP) == 0)
+ g[i++] = 'w';
+ if ((mask & S_IXGRP) == 0)
+ g[i++] = 'x';
+ g[i] = '\0';
+
+ i = 0;
+ if ((mask & S_IROTH) == 0)
+ o[i++] = 'r';
+ if ((mask & S_IWOTH) == 0)
+ o[i++] = 'w';
+ if ((mask & S_IXOTH) == 0)
+ o[i++] = 'x';
+ o[i] = '\0';
+
+ out1fmt("u=%s,g=%s,o=%s\n", u, g, o);
+ } else {
+ out1fmt("%.4o\n", mask);
+ }
} else {
- mask = 0;
- do {
- if ((unsigned)(i = *p - '0') >= 8)
- error("Illegal number: %s", argv[1]);
- mask = (mask << 3) + i;
- } while (*++p != '\0');
- umask(mask);
+ if (isdigit(*ap)) {
+ mask = 0;
+ do {
+ if (*ap >= '8' || *ap < '0')
+ error("Illegal number: %s", argv[1]);
+ mask = (mask << 3) + (*ap - '0');
+ } while (*++ap != '\0');
+ umask(mask);
+ } else {
+ void *set;
+ if ((set = setmode (ap)) == 0)
+ error("Illegal number: %s", ap);
+
+ mask = getmode (set, ~mask & 0777);
+ umask(~mask & 0777);
+ }
}
return 0;
}
+/*
+ * ulimit builtin
+ *
+ * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
+ * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
+ * ash by J.T. Conklin.
+ *
+ * Public domain.
+ */
-#if BSD
-struct restab {
- int resource;
- int scale;
- char *descript;
+struct limits {
+ const char *name;
+ int cmd;
+ int factor; /* multiply by to get rlim_{cur,max} values */
+ char option;
};
-/* multi-purpose */
-#define RLIMIT_UNSPEC (-2)
-
-/* resource */
-#define RLIMIT_ALL (-1)
-
-/* mode */
-#define RLIMIT_SHOW 0
-#define RLIMIT_SET 1
-
-/* what */
-#define RLIMIT_SOFT 1
-#define RLIMIT_HARD 2
-
-static struct restab restab[] = {
- {RLIMIT_CORE, 512, "coredump(512-blocks) "},
- {RLIMIT_CPU, 1, "time(seconds) "},
- {RLIMIT_DATA, 1024, "datasize(kilobytes) "},
- {RLIMIT_FSIZE, 512, "filesize(512-blocks) "},
- {RLIMIT_MEMLOCK, 1024, "lockedmem(kilobytes) "},
- {RLIMIT_NOFILE, 1, "nofiles(descriptors) "},
- {RLIMIT_NPROC, 1, "userprocs(max) "},
- {RLIMIT_RSS, 1024, "memoryuse(kilobytes) "},
- {RLIMIT_STACK, 1024, "stacksize(kilobytes) "}
+static const struct limits limits[] = {
+#ifdef RLIMIT_CPU
+ { "time(seconds)", RLIMIT_CPU, 1, 't' },
+#endif
+#ifdef RLIMIT_FSIZE
+ { "file(512-blocks)", RLIMIT_FSIZE, 512, 'f' },
+#endif
+#ifdef RLIMIT_DATA
+ { "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
+#endif
+#ifdef RLIMIT_STACK
+ { "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
+#endif
+#ifdef RLIMIT_CORE
+ { "coredump(512-blocks)", RLIMIT_CORE, 512, 'c' },
+#endif
+#ifdef RLIMIT_RSS
+ { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
+#endif
+#ifdef RLIMIT_MEMLOCK
+ { "lockedmem(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
+#endif
+#ifdef RLIMIT_NPROC
+ { "process(processes)", RLIMIT_NPROC, 1, 'u' },
+#endif
+#ifdef RLIMIT_NOFILE
+ { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
+#endif
+#ifdef RLIMIT_VMEM
+ { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
+#endif
+#ifdef RLIMIT_SWAP
+ { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' },
+#endif
+ { (char *) 0, 0, 0, '\0' }
};
-/* get entry into above table */
-static struct restab *
-find_resource(resource) {
- int i;
- struct restab *rp;
-
- for(i = 0, rp = restab;
- i < sizeof restab / sizeof(struct restab);
- i++, rp++)
- if(rp->resource == resource)
- return rp;
- error("internal error: resource not in table");
- return 0;
-}
-
-static void
-print_resource(rp, what, with_descript) struct restab *rp; {
- struct rlimit rlim;
+int
+ulimitcmd(argc, argv)
+ int argc;
+ char **argv;
+{
+ register int c;
quad_t val;
+ enum { SOFT = 0x1, HARD = 0x2 }
+ how = SOFT | HARD;
+ const struct limits *l;
+ int set, all = 0;
+ int optc, what;
+ struct rlimit limit;
- (void)getrlimit(rp->resource, &rlim);
- val = (what == RLIMIT_SOFT)?
- rlim.rlim_cur: rlim.rlim_max;
- if(with_descript)
- out1str(rp->descript);
- if(val == RLIM_INFINITY)
- out1str("unlimited\n");
- else {
- val /= (quad_t)rp->scale;
- if(val > (quad_t)ULONG_MAX)
- out1fmt("> %lu\n", (unsigned long)ULONG_MAX);
- else
- out1fmt("%lu\n", (unsigned long)val);
- }
-}
-
-ulimitcmd(argc, argv) char **argv; {
- struct rlimit rlim;
- char *p;
- int i;
- int resource = RLIMIT_UNSPEC;
- quad_t val;
- int what = RLIMIT_UNSPEC;
- int mode = RLIMIT_UNSPEC;
- int errs = 0, arg = 1;
- struct restab *rp;
- extern int optreset; /* XXX should be declared in <stdlib.h> */
-
- opterr = 0; /* use own error processing */
- optreset = 1;
- optind = 1;
- while ((i = getopt(argc, argv, "HSacdfnstmlu")) != EOF) {
- arg++;
- switch(i) {
+ what = 'f';
+ while ((optc = nextopt("HSatfdsmcnpl")) != '\0')
+ switch (optc) {
case 'H':
- if(what == RLIMIT_UNSPEC) what = 0;
- what |= RLIMIT_HARD;
+ how = HARD;
break;
case 'S':
- if(what == RLIMIT_UNSPEC) what = 0;
- what |= RLIMIT_SOFT;
+ how = SOFT;
break;
case 'a':
- if(resource != RLIMIT_UNSPEC) errs++;
- resource = RLIMIT_ALL;
- mode = RLIMIT_SHOW;
- break;
- case 'c':
- if(resource != RLIMIT_UNSPEC) errs++;
- resource = RLIMIT_CORE;
- break;
- case 'd':
- if(resource != RLIMIT_UNSPEC) errs++;
- resource = RLIMIT_DATA;
- break;
- case 'f':
- if(resource != RLIMIT_UNSPEC) errs++;
- resource = RLIMIT_FSIZE;
- break;
- case 'n':
- if(resource != RLIMIT_UNSPEC) errs++;
- resource = RLIMIT_NOFILE;
- break;
- case 's':
- if(resource != RLIMIT_UNSPEC) errs++;
- resource = RLIMIT_STACK;
- break;
- case 't':
- if(resource != RLIMIT_UNSPEC) errs++;
- resource = RLIMIT_CPU;
- break;
- case 'm':
- if(resource != RLIMIT_UNSPEC) errs++;
- resource = RLIMIT_RSS;
+ all = 1;
break;
- case 'l':
- if(resource != RLIMIT_UNSPEC) errs++;
- resource = RLIMIT_MEMLOCK;
- break;
- case 'u':
- if(resource != RLIMIT_UNSPEC) errs++;
- resource = RLIMIT_NPROC;
- break;
- case '?':
- error("illegal option -%c", optopt);
+ default:
+ what = optc;
}
- }
- argc -= optind;
- argv += optind;
- if(argc > 1)
- error("too many arguments");
- if(argc == 0)
- mode = RLIMIT_SHOW;
- else if (resource == RLIMIT_ALL)
- errs++;
- else
- mode = RLIMIT_SET;
- if(mode == RLIMIT_UNSPEC)
- mode = RLIMIT_SHOW;
- if(resource == RLIMIT_UNSPEC)
- resource = RLIMIT_FSIZE;
- if(what == RLIMIT_UNSPEC)
- what = (mode == RLIMIT_SHOW)?
- RLIMIT_SOFT: (RLIMIT_SOFT|RLIMIT_HARD);
- if(mode == RLIMIT_SHOW && what == (RLIMIT_SOFT|RLIMIT_HARD))
- errs++;
- if(errs)
- error("Wrong option combination");
-
- if(resource == RLIMIT_ALL)
- for(i = 0; i < sizeof restab / sizeof(struct restab); i++)
- print_resource(restab + i, what, 1);
- else if(mode == RLIMIT_SHOW)
- print_resource(find_resource(resource), what, 0);
- else {
- rp = find_resource(resource);
- if(strcmp(argv[0], "unlimited") == 0)
+ for (l = limits; l->name && l->option != what; l++)
+ ;
+ if (!l->name)
+ error("ulimit: internal error (%c)\n", what);
+
+ set = *argptr ? 1 : 0;
+ if (set) {
+ char *p = *argptr;
+
+ if (all || argptr[1])
+ error("ulimit: too many arguments\n");
+ if (strcmp(p, "unlimited") == 0)
val = RLIM_INFINITY;
else {
- val = 0;
- p = argv[0];
- do {
- if((i = *p - '0') < 0 || i > 9)
- error("Illegal number: %s", argv[0]);
- val = (10 * val) + (quad_t)i;
- } while (*++p != '\0');
- val *= (quad_t)rp->scale;
+ val = (quad_t) 0;
+
+ while ((c = *p++) >= '0' && c <= '9')
+ {
+ val = (val * 10) + (long)(c - '0');
+ if (val < (quad_t) 0)
+ break;
+ }
+ if (c)
+ error("ulimit: bad number\n");
+ val *= l->factor;
+ }
+ }
+ if (all) {
+ for (l = limits; l->name; l++) {
+ getrlimit(l->cmd, &limit);
+ if (how & SOFT)
+ val = limit.rlim_cur;
+ else if (how & HARD)
+ val = limit.rlim_max;
+
+ out1fmt("%-20s ", l->name);
+ if (val == RLIM_INFINITY)
+ out1fmt("unlimited\n");
+ else
+ {
+ val /= l->factor;
+ out1fmt("%ld\n", (long) val);
+ }
}
- (void)getrlimit(resource, &rlim);
- if(what & RLIMIT_HARD)
- rlim.rlim_max = val;
- if(what & RLIMIT_SOFT)
- rlim.rlim_cur = val;
- if(setrlimit(resource, &rlim) == -1) {
- outfmt(&errout, "ulimit: bad limit: %s\n",
- strerror(errno));
- return 1;
+ return 0;
+ }
+
+ getrlimit(l->cmd, &limit);
+ if (set) {
+ if (how & SOFT)
+ limit.rlim_cur = val;
+ if (how & HARD)
+ limit.rlim_max = val;
+ if (setrlimit(l->cmd, &limit) < 0)
+ error("ulimit: bad limit\n");
+ } else {
+ if (how & SOFT)
+ val = limit.rlim_cur;
+ else if (how & HARD)
+ val = limit.rlim_max;
+ }
+
+ if (!set) {
+ if (val == RLIM_INFINITY)
+ out1fmt("unlimited\n");
+ else
+ {
+ val /= l->factor;
+ out1fmt("%ld\n", (long) val);
}
}
return 0;
}
-#else /* !BSD */
-#error ulimit() not implemented
-#endif /* BSD */
OpenPOWER on IntegriCloud