141 lines
2.7 KiB
C
141 lines
2.7 KiB
C
/*
|
|
* 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.
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
#include <sys/resource.h>
|
|
|
|
#include "shell.h"
|
|
#include "options.h"
|
|
#include "output.h"
|
|
|
|
struct limits {
|
|
const char *name;
|
|
int cmd;
|
|
int factor; /* multiply by to get rlim_{cur,max} values */
|
|
char option;
|
|
};
|
|
|
|
static const struct limits limits[] = {
|
|
{ "time(seconds)", RLIMIT_CPU, 1, 't' },
|
|
{ "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
|
|
{ "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
|
|
{ "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
|
|
{ "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
|
|
{ "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
|
|
{ "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
|
|
#ifdef RLIMIT_VMEM
|
|
{ "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
|
|
#endif
|
|
#ifdef RLIMIT_SWAP
|
|
{ "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' },
|
|
#endif
|
|
{ (char *) 0 }
|
|
};
|
|
|
|
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;
|
|
|
|
what = 'f';
|
|
while ((optc = nextopt("HSatfdsmcn")) != '\0')
|
|
switch (optc) {
|
|
case 'H':
|
|
how = HARD;
|
|
break;
|
|
case 'S':
|
|
how = SOFT;
|
|
break;
|
|
case 'a':
|
|
all = 1;
|
|
break;
|
|
default:
|
|
what = optc;
|
|
}
|
|
|
|
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");
|
|
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);
|
|
}
|
|
}
|
|
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;
|
|
}
|