summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1995-10-19 18:42:12 +0000
committerjoerg <joerg@FreeBSD.org>1995-10-19 18:42:12 +0000
commit944d72963926679a269cec39063fe921fdfb73ff (patch)
tree34fc9c6cecb8198ab3b89983e080bd34b2203ea9 /bin
parent6d13f9a708f62766aa05501fc6b9b931ff1e726f (diff)
downloadFreeBSD-src-944d72963926679a269cec39063fe921fdfb73ff.zip
FreeBSD-src-944d72963926679a269cec39063fe921fdfb73ff.tar.gz
Implement the "ulimit" builtin. This is the analogon to csh's "limit"
command and badly needed in sh(1) for everybody who wants to modify the system-wide limits from inside /etc/rc. The options are similar to other system's implemantations of this command, with the FreeBSD additions for -m (memoryuse) and -p (max processes) that are not available on other systems.
Diffstat (limited to 'bin')
-rwxr-xr-xbin/sh/builtins3
-rw-r--r--bin/sh/miscbltin.c215
-rw-r--r--bin/sh/sh.154
3 files changed, 269 insertions, 3 deletions
diff --git a/bin/sh/builtins b/bin/sh/builtins
index 9624718..a0b0f8f 100755
--- a/bin/sh/builtins
+++ b/bin/sh/builtins
@@ -35,7 +35,7 @@
# SUCH DAMAGE.
#
# @(#)builtins 8.1 (Berkeley) 5/31/93
-# $Id$
+# $Id: builtins,v 1.2 1994/09/24 02:57:23 davidg Exp $
#
# This file lists all the builtin commands. The first column is the name
@@ -83,6 +83,7 @@ setvarcmd setvar
shiftcmd shift
trapcmd trap
truecmd : true
+ulimitcmd ulimit
umaskcmd umask
unaliascmd unalias
unsetcmd unset
diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c
index 52a66e7..be7f0f7 100644
--- a/bin/sh/miscbltin.c
+++ b/bin/sh/miscbltin.c
@@ -4,6 +4,7 @@
*
* 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
@@ -33,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: miscbltin.c,v 1.2 1994/09/24 02:57:52 davidg Exp $
*/
#ifndef lint
@@ -52,6 +53,18 @@ 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 */
@@ -166,3 +179,203 @@ umaskcmd(argc, argv) char **argv; {
}
return 0;
}
+
+
+#if BSD
+struct restab {
+ int resource;
+ int scale;
+ char *descript;
+};
+
+/* 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, "processes(max) "},
+ {RLIMIT_RSS, 1024, "memoryuse(kilobytes) "},
+ {RLIMIT_STACK, 1024, "stacksize(kilobytes) "}
+};
+
+/* 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;
+ quad_t val;
+
+ (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, "HSacdfnstmlp")) != EOF) {
+ arg++;
+ switch(i) {
+ case 'H':
+ if(what == RLIMIT_UNSPEC) what = 0;
+ what |= RLIMIT_HARD;
+ break;
+ case 'S':
+ if(what == RLIMIT_UNSPEC) what = 0;
+ what |= RLIMIT_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;
+ break;
+ case 'l':
+ if(resource != RLIMIT_UNSPEC) errs++;
+ resource = RLIMIT_MEMLOCK;
+ break;
+ case 'p':
+ if(resource != RLIMIT_UNSPEC) errs++;
+ resource = RLIMIT_NPROC;
+ break;
+ case '?':
+ error("illegal option -%c", optopt);
+ }
+ }
+
+ 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)
+ 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;
+ }
+ (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;
+}
+#else /* !BSD */
+#error ulimit() not implemented
+#endif /* BSD */
diff --git a/bin/sh/sh.1 b/bin/sh/sh.1
index 989b214..a5201a2 100644
--- a/bin/sh/sh.1
+++ b/bin/sh/sh.1
@@ -33,7 +33,9 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)sh.1 8.4 (Berkeley) 4/18/94
-.\" $Id: sh.1,v 1.2 1994/09/24 02:58:13 davidg Exp $
+.\" $Id: sh.1,v 1.3 1995/05/05 16:49:15 adam Exp $
+.\"
+.\"
.\"
.na
.TH SH 1
@@ -1277,6 +1279,56 @@ resets trapped (but not ignored) signals to the
default action. The trap command has no effect on
signals that were ignored on entry to the shell.
.TP
+ulimit [ -HSacdflmnpst ] [ limit ]
+Set or display resource limits (see getrlimit(2)).
+If ``limit'' is specified, the named resource will be set;
+otherwise the current resource value will be displayed.
+.br
+If ``-H'' is specified, the hard limits will be
+set or displayed. While everybody is allowed to reduce a
+hard limit, only the superuser can increase it. Option ``-S''
+specifies the soft limits instead. When displaying limits,
+only one of ``-S'' or ``-H'' can be given. The default is
+to display the soft limits, and to set both, the hard and
+the soft limits.
+.br
+Option ``-a'' requests to display all resources. The parameter
+``limit'' is not acceptable in this mode.
+.br
+The remaining options specify which resource value is to be
+displayed or modified. They are mutually exclusive.
+.RS +.7i
+.TP 2
+-c coredumpsize
+The maximal size of core dump files, in 512-byte blocks.
+.TP 2
+-d datasize
+The maximal size of the data segment of a process, in kilobytes.
+.TP 2
+-f filesize
+The maximal size of a file, in 512-byte blocks. This is the
+default.
+.TP 2
+-l lockedmem
+The maximal size of memory that can be locked by a process, in
+kilobytes.
+.TP 2
+-m memoryuse
+The maximal resident set size of a process, in kilobytes.
+.TP 2
+-n nofiles
+The maximal number of descriptors that could be opened by a process.
+.TP 2
+-p procmax
+The maximal number of simultaneous processes for this user ID.
+.TP 2
+-s stacksize
+The maximal size of the stack segment, in kilobytes.
+.TP 2
+-t time
+The maximal amount of CPU time to be used by each process, in seconds.
+.RE
+.TP
umask [ mask ]
Set the value of umask (see umask(2)) to the specified octal value.
If the argument is omitted, the
OpenPOWER on IntegriCloud