more clueful (automatic) getopt string generation

This commit is contained in:
tg
2013-11-17 22:21:18 +00:00
parent 44a58fb3e9
commit d1245ee13a
5 changed files with 335 additions and 176 deletions

208
funcs.c
View File

@ -38,7 +38,7 @@
#endif
#endif
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.249 2013/11/17 22:20:20 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.250 2013/11/17 22:21:17 tg Exp $");
#if HAVE_KILLPG
/*
@ -3341,16 +3341,6 @@ ptest_error(Test_env *te, int ofs, const char *msg)
#define SOFT 0x1
#define HARD 0x2
struct limits {
const char *name;
int resource; /* resource to get/set */
unsigned int factor; /* multiply by to get rlim_{cur,max} values */
char option;
};
static void print_ulimit(const struct limits *, int);
static int set_ulimit(const struct limits *, const char *, int);
/* Magic to divine the 'm' and 'v' limits */
#ifdef RLIMIT_AS
@ -3393,159 +3383,38 @@ static int set_ulimit(const struct limits *, const char *, int);
#undef ULIMIT_M_IS_VMEM
#endif
#if defined(ULIMIT_M_IS_RSS) && defined(ULIMIT_M_IS_VMEM)
# error nonsensical m ulimit
#endif
#if defined(ULIMIT_V_IS_VMEM) && defined(ULIMIT_V_IS_AS)
# error nonsensical v ulimit
#endif
#define RLIMITS_DEFNS
#include "rlimits.gen"
static void print_ulimit(const struct limits *, int);
static int set_ulimit(const struct limits *, const char *, int);
static const struct limits * const rlimits[] = {
#define RLIMITS_ITEMS
#include "rlimits.gen"
};
static const char rlimits_opts[] =
#define RLIMITS_OPTCS
#include "rlimits.gen"
;
int
c_ulimit(const char **wp)
{
static const struct limits limits[] = {
/* do not use options -H, -S or -a or change the order */
#ifdef RLIMIT_CPU
{ "time(cpu-seconds)", RLIMIT_CPU, 1, 't' },
#endif
#ifdef RLIMIT_FSIZE
{ "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
#endif
#ifdef RLIMIT_CORE
{ "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
#endif
#ifdef RLIMIT_DATA
{ "data(KiB)", RLIMIT_DATA, 1024, 'd' },
#endif
#ifdef RLIMIT_STACK
{ "stack(KiB)", RLIMIT_STACK, 1024, 's' },
#endif
#ifdef RLIMIT_MEMLOCK
{ "lockedmem(KiB)", RLIMIT_MEMLOCK, 1024, 'l' },
#endif
#ifdef RLIMIT_NOFILE
{ "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
#endif
#ifdef RLIMIT_NPROC
{ "processes", RLIMIT_NPROC, 1, 'p' },
#endif
#ifdef RLIMIT_SWAP
{ "swap(KiB)", RLIMIT_SWAP, 1024, 'w' },
#endif
#ifdef RLIMIT_TIME
{ "humantime(seconds)", RLIMIT_TIME, 1, 'T' },
#endif
#ifdef RLIMIT_NOVMON
{ "vnodemonitors", RLIMIT_NOVMON, 1, 'V' },
#endif
#ifdef RLIMIT_SIGPENDING
{ "sigpending", RLIMIT_SIGPENDING, 1, 'i' },
#endif
#ifdef RLIMIT_MSGQUEUE
{ "msgqueue(bytes)", RLIMIT_MSGQUEUE, 1, 'q' },
#endif
#ifdef RLIMIT_AIO_MEM
{ "AIOlockedmem(KiB)", RLIMIT_AIO_MEM, 1024, 'M' },
#endif
#ifdef RLIMIT_AIO_OPS
{ "AIOoperations", RLIMIT_AIO_OPS, 1, 'O' },
#endif
#ifdef RLIMIT_TCACHE
{ "cachedthreads", RLIMIT_TCACHE, 1, 'C' },
#endif
#ifdef RLIMIT_SBSIZE
{ "sockbufsiz(KiB)", RLIMIT_SBSIZE, 1024, 'B' },
#endif
#ifdef RLIMIT_PTHREAD
{ "threadsperprocess", RLIMIT_PTHREAD, 1, 'P' },
#endif
#ifdef RLIMIT_NICE
{ "maxnice", RLIMIT_NICE, 1, 'e' },
#endif
#ifdef RLIMIT_RTPRIO
{ "maxrtprio", RLIMIT_RTPRIO, 1, 'r' },
#endif
#if defined(ULIMIT_M_IS_RSS)
{ "resident-set(KiB)", RLIMIT_RSS, 1024, 'm' },
#elif defined(ULIMIT_M_IS_VMEM)
{ "memory(KiB)", RLIMIT_VMEM, 1024, 'm' },
#endif
#if defined(ULIMIT_V_IS_VMEM)
{ "virtual-memory(KiB)", RLIMIT_VMEM, 1024, 'v' },
#elif defined(ULIMIT_V_IS_AS)
{ "address-space(KiB)", RLIMIT_AS, 1024, 'v' },
#endif
{ NULL, 0, 0, 0 }
};
static const char opts[] = "a"
#ifdef RLIMIT_SBSIZE
"B"
#endif
#ifdef RLIMIT_TCACHE
"C"
#endif
#ifdef RLIMIT_CORE
"c"
#endif
#ifdef RLIMIT_DATA
"d"
#endif
#ifdef RLIMIT_NICE
"e"
#endif
#ifdef RLIMIT_FSIZE
"f"
#endif
"H"
#ifdef RLIMIT_SIGPENDING
"i"
#endif
#ifdef RLIMIT_MEMLOCK
"l"
#endif
#ifdef RLIMIT_AIO_MEM
"M"
#endif
#if defined(ULIMIT_M_IS_RSS) || defined(ULIMIT_M_IS_VMEM)
"m"
#endif
#ifdef RLIMIT_NOFILE
"n"
#endif
#ifdef RLIMIT_AIO_OPS
"O"
#endif
#ifdef RLIMIT_PTHREAD
"P"
#endif
#ifdef RLIMIT_NPROC
"p"
#endif
#ifdef RLIMIT_MSGQUEUE
"q"
#endif
#ifdef RLIMIT_RTPRIO
"r"
#endif
"S"
#ifdef RLIMIT_STACK
"s"
#endif
#ifdef RLIMIT_TIME
"T"
#endif
#ifdef RLIMIT_CPU
"t"
#endif
#ifdef RLIMIT_NOVMON
"V"
#endif
#if defined(ULIMIT_V_IS_VMEM) || defined(ULIMIT_V_IS_AS)
"v"
#endif
#ifdef RLIMIT_SWAP
"w"
#endif
;
size_t i = 0;
int how = SOFT | HARD, optc, what = 'f';
bool all = false;
const struct limits *l;
while ((optc = ksh_getopt(wp, &builtin_opt, opts)) != -1)
while ((optc = ksh_getopt(wp, &builtin_opt, rlimits_opts)) != -1)
switch (optc) {
case 'H':
how = HARD;
@ -3557,31 +3426,32 @@ c_ulimit(const char **wp)
all = true;
break;
case '?':
bi_errorf("usage: ulimit [-%s] [value]", opts);
bi_errorf("usage: ulimit [-%s] [value]", rlimits_opts);
return (1);
default:
what = optc;
}
for (l = limits; l->name && l->option != what; l++)
;
if (!l->name) {
internal_warningf("ulimit: %c", what);
return (1);
while (i < NELEM(rlimits)) {
if (rlimits[i]->optchar == what)
goto found;
++i;
}
internal_warningf("ulimit: %c", what);
return (1);
found:
if (wp[builtin_opt.optind]) {
if (all || wp[builtin_opt.optind + 1]) {
bi_errorf("too many arguments");
return (1);
}
return (set_ulimit(l, wp[builtin_opt.optind], how));
return (set_ulimit(rlimits[i], wp[builtin_opt.optind], how));
}
if (!all)
print_ulimit(l, how);
else for (l = limits; l->name; l++) {
shprintf("%-20s ", l->name);
print_ulimit(l, how);
print_ulimit(rlimits[i], how);
else for (i = 0; i < NELEM(rlimits); ++i) {
shprintf("%-20s ", rlimits[i]->name);
print_ulimit(rlimits[i], how);
}
return (0);
}