summaryrefslogtreecommitdiff
path: root/Src/Builtins/rlimits.c
diff options
context:
space:
mode:
authorDaniel Shahaf <danielsh@apache.org>2020-03-07 21:36:46 +0000
committerDaniel Shahaf <danielsh@apache.org>2020-03-07 21:36:46 +0000
commit6fc8e8628f9c3da6e4b83c3de67e44376708cbcb (patch)
treec711b1d53564bcca757799e1d734e24859c5f32e /Src/Builtins/rlimits.c
parent0d3d07c56f75064310271bf4469c5c9c13145d58 (diff)
parentdd50f125b5eb65896642d2ff664adefd33f1004c (diff)
downloadzsh-6fc8e8628f9c3da6e4b83c3de67e44376708cbcb.tar.gz
zsh-6fc8e8628f9c3da6e4b83c3de67e44376708cbcb.zip
Merge remote-tracking branch 'origin/master' into 5.9
* Test/D02glob.ztst: On the "unreadable directories can be globbed (users/24619, users/24626)" test, resolve conflicts by removing the Cygwin-only skip that has been added in master, since the test is passing on this branch. This effectively reverts workers/45492. See discussion starting in workers/45504. * origin/master: unposted: Remove 'sgi', as that OpenBSD port has been discontinued. 45509: fix typos in B01cd.ztst 45490 (+45495 and a test): refactor rlimits.c github #49: Fix typo: longson should be loongson users/24710: Fix job control problem with sudo. 45492: skip test added by users/24633 on Cygwin 45488: COMP_WORDS for bash need "$@"-style quoting 45487: Missing mod_export declarations for AIX 45447: Complete vcs_info_hookadd and vcs_info_hookdel. Expose _vcs_info_hooks as a top-level helper function. 45463: test: kill: Document why we use SIGURG 45453: builtins: kill: Do not signal current process group when pid is empty 45452: builtins: kill: Add `kill ''` regression test with explicit sigspec 45451: builtins: kill: Add basic test suite github #48/0002: vcs_info git: properly detect bare repositories github #48/0001: vcs_info git: avoid warnings in bare repositories unposted: Post-release version bump unposted: Release 5.8 CVE-2019-20044: Update change log for preceding commits Update NEWS/README Add unsetopt/PRIVILEGED tests Clean up error-message white space Improve PRIVILEGED fixes (again) Improve PRIVILEGED fixes Drop privileges securely unposted: V01zmodload: Fix failing test from workers/45385 45423: _su: Improve arg handling, shell look-ups unposted: _zip: Recognise '--' 45385: Add a test for 'zmodload -Fa' preemptively disabling ("blacklisting"?) features. unposted: Test release: 5.7.1-test-3 zsh/system: Fix infinite loop in sysread _diff_options: Restore -w completion lost in workers/43351 unposted: Fix ChangeLog typo. 45368: Add tests for workers/45367's issue about double slashes in 'cd -P' and /home/daniel/in/zsh. 45373: Fix ERR_EXIT bug in else branch of if. 45372: Record a symlink loop bug involving :P 45365: _git: Fix __git_recent_branches for the case when a commit has an empty message 45343: Queue signals around arithmetic evaluations 45344: Document where third-party completion functions should be installed. 45345: internal: ztst.vim: Fix highlighting of zsh comments in test payload unposted: internal: Add some comments and fix indentation. No functional change. 45340: internal: Document the difference between paramtab and realparamtab. 45332: _git: add completion for git-version _brace_parameter: add missing \ Conflicts: ChangeLog Test/D02glob.ztst Test/V01zmodload.ztst
Diffstat (limited to 'Src/Builtins/rlimits.c')
-rw-r--r--Src/Builtins/rlimits.c692
1 files changed, 263 insertions, 429 deletions
diff --git a/Src/Builtins/rlimits.c b/Src/Builtins/rlimits.c
index 6b552f3a9..b9128433f 100644
--- a/Src/Builtins/rlimits.c
+++ b/Src/Builtins/rlimits.c
@@ -32,20 +32,7 @@
#if defined(HAVE_GETRLIMIT) && defined(RLIM_INFINITY)
-#if defined(HAVE_RLIMIT_POSIXLOCKS) && !defined(HAVE_RLIMIT_LOCKS)
-# define RLIMIT_LOCKS RLIMIT_POSIXLOCKS
-# define HAVE_RLIMIT_LOCKS 1
-#endif
-
-#if defined(HAVE_RLIMIT_NTHR) && !defined(HAVE_RLIMIT_PTHREAD)
-# define RLIMIT_PTHREAD RLIMIT_NTHR
-# define HAVE_RLIMIT_PTHREAD 1
-# define THREAD_FMT "-T: threads "
-#else
-# define THREAD_FMT "-T: threads per process "
-#endif
-
-enum {
+enum zlimtype {
ZLIMTYPE_MEMORY,
ZLIMTYPE_NUMBER,
ZLIMTYPE_TIME,
@@ -53,11 +40,214 @@ enum {
ZLIMTYPE_UNKNOWN
};
-/* Generated rec array containing limits required for the limit builtin. *
- * They must appear in this array in numerical order of the RLIMIT_* macros. */
+typedef struct resinfo_T {
+ int res; /* RLIMIT_XXX */
+ char* name; /* used by limit builtin */
+ enum zlimtype type;
+ int unit; /* 1, 512, or 1024 */
+ char opt; /* option character */
+ char* descr; /* used by ulimit builtin */
+} resinfo_T;
+
+/* table of known resources */
+static const resinfo_T known_resources[] = {
+ {RLIMIT_CPU, "cputime", ZLIMTYPE_TIME, 1,
+ 't', "cpu time (seconds)"},
+ {RLIMIT_FSIZE, "filesize", ZLIMTYPE_MEMORY, 512,
+ 'f', "file size (blocks)"},
+ {RLIMIT_DATA, "datasize", ZLIMTYPE_MEMORY, 1024,
+ 'd', "data seg size (kbytes)"},
+ {RLIMIT_STACK, "stacksize", ZLIMTYPE_MEMORY, 1024,
+ 's', "stack size (kbytes)"},
+ {RLIMIT_CORE, "coredumpsize", ZLIMTYPE_MEMORY, 512,
+ 'c', "core file size (blocks)"},
+# ifdef HAVE_RLIMIT_NOFILE
+ {RLIMIT_NOFILE, "descriptors", ZLIMTYPE_NUMBER, 1,
+ 'n', "file descriptors"},
+# endif
+# if defined(HAVE_RLIMIT_AS) && !defined(RLIMIT_VMEM_IS_AS)
+ {RLIMIT_AS, "addressspace", ZLIMTYPE_MEMORY, 1024,
+ 'v', "address space (kbytes)"},
+# endif
+# if defined(HAVE_RLIMIT_RSS) && !defined(RLIMIT_VMEM_IS_RSS) && !defined(RLIMIT_RSS_IS_AS)
+ {RLIMIT_RSS, "resident", ZLIMTYPE_MEMORY, 1024,
+ 'm', "resident set size (kbytes)"},
+# endif
+# if defined(HAVE_RLIMIT_VMEM)
+ {RLIMIT_VMEM,
+# if defined(RLIMIT_VMEM_IS_RSS)
+ "resident", ZLIMTYPE_MEMORY, 1024,
+ 'm', "memory size (kbytes)"},
+# else
+ "vmemorysize", ZLIMTYPE_MEMORY, 1024,
+ 'v', "virtual memory size (kbytes)"},
+# endif
+# endif
+# ifdef HAVE_RLIMIT_NPROC
+ {RLIMIT_NPROC, "maxproc", ZLIMTYPE_NUMBER, 1,
+ 'u', "processes"},
+# endif
+# ifdef HAVE_RLIMIT_MEMLOCK
+ {RLIMIT_MEMLOCK, "memorylocked", ZLIMTYPE_MEMORY, 1024,
+ 'l', "locked-in-memory size (kbytes)"},
+# endif
+ /* Linux */
+# ifdef HAVE_RLIMIT_LOCKS
+ {RLIMIT_LOCKS, "maxfilelocks", ZLIMTYPE_NUMBER, 1,
+ 'x', "file locks"},
+# endif
+# ifdef HAVE_RLIMIT_SIGPENDING
+ {RLIMIT_SIGPENDING, "sigpending", ZLIMTYPE_NUMBER, 1,
+ 'i', "pending signals"},
+# endif
+# ifdef HAVE_RLIMIT_MSGQUEUE
+ {RLIMIT_MSGQUEUE, "msgqueue", ZLIMTYPE_NUMBER, 1,
+ 'q', "bytes in POSIX msg queues"},
+# endif
+# ifdef HAVE_RLIMIT_NICE
+ {RLIMIT_NICE, "nice", ZLIMTYPE_NUMBER, 1,
+ 'e', "max nice"},
+# endif
+# ifdef HAVE_RLIMIT_RTPRIO
+ {RLIMIT_RTPRIO, "rt_priority", ZLIMTYPE_NUMBER, 1,
+ 'r', "max rt priority"},
+# endif
+# ifdef HAVE_RLIMIT_RTTIME
+ {RLIMIT_RTTIME, "rt_time", ZLIMTYPE_MICROSECONDS, 1,
+ 'N', "rt cpu time (microseconds)"},
+# endif
+ /* BSD */
+# ifdef HAVE_RLIMIT_SBSIZE
+ {RLIMIT_SBSIZE, "sockbufsize", ZLIMTYPE_MEMORY, 1,
+ 'b', "socket buffer size (bytes)"},
+# endif
+# ifdef HAVE_RLIMIT_KQUEUES /* FreeBSD */
+ {RLIMIT_KQUEUES, "kqueues", ZLIMTYPE_NUMBER, 1,
+ 'k', "kqueues"},
+# endif
+# ifdef HAVE_RLIMIT_NPTS /* FreeBSD */
+ {RLIMIT_NPTS, "pseudoterminals", ZLIMTYPE_NUMBER, 1,
+ 'p', "pseudo-terminals"},
+# endif
+# ifdef HAVE_RLIMIT_SWAP /* FreeBSD */
+ {RLIMIT_SWAP, "swapsize", ZLIMTYPE_MEMORY, 1024,
+ 'w', "swap size (kbytes)"},
+# endif
+# ifdef HAVE_RLIMIT_UMTXP /* FreeBSD */
+ {RLIMIT_UMTXP, "umtxp", ZLIMTYPE_NUMBER, 1,
+ 'o', "umtx shared locks"},
+# endif
+
+# ifdef HAVE_RLIMIT_POSIXLOCKS /* DragonFly */
+ {RLIMIT_POSIXLOCKS, "posixlocks", ZLIMTYPE_NUMBER, 1,
+ 'x', "number of POSIX locks"},
+# endif
+# if defined(HAVE_RLIMIT_NTHR) && !defined(HAVE_RLIMIT_RTPRIO) /* Net/OpenBSD */
+ {RLIMIT_NTHR, "maxpthreads", ZLIMTYPE_NUMBER, 1,
+ 'r', "threads"},
+# endif
+ /* others */
+# if defined(HAVE_RLIMIT_PTHREAD) && !defined(HAVE_RLIMIT_NTHR) /* IRIX ? */
+ {RLIMIT_PTHREAD, "maxpthreads", ZLIMTYPE_NUMBER, 1,
+ 'T', "threads per process"},
+# endif
+# ifdef HAVE_RLIMIT_AIO_MEM /* HP-UX ? */
+ {RLIMIT_AIO_MEM, "aiomemorylocked", ZLIMTYPE_MEMORY, 1024,
+ 'N', "AIO locked-in-memory (kbytes)"},
+# endif
+# ifdef HAVE_RLIMIT_AIO_OPS /* HP-UX ? */
+ {RLIMIT_AIO_OPS, "aiooperations", ZLIMTYPE_NUMBER, 1,
+ 'N', "AIO operations"},
+# endif
+# ifdef HAVE_RLIMIT_TCACHE /* HP-UX ? */
+ {RLIMIT_TCACHE, "cachedthreads", ZLIMTYPE_NUMBER, 1,
+ 'N', "cached threads"},
+# endif
+};
-# include "rlimits.h"
+/* resinfo[RLIMIT_XXX] points to the corresponding entry
+ * in known_resources[] */
+static const resinfo_T **resinfo;
+/**/
+static void
+set_resinfo(void)
+{
+ int i;
+
+ resinfo = (const resinfo_T **)zshcalloc(RLIM_NLIMITS*sizeof(resinfo_T *));
+
+ for (i=0; i<sizeof(known_resources)/sizeof(resinfo_T); ++i) {
+ resinfo[known_resources[i].res] = &known_resources[i];
+ }
+ for (i=0; i<RLIM_NLIMITS; ++i) {
+ if (!resinfo[i]) {
+ /* unknown resource */
+ resinfo_T *info = (resinfo_T *)zshcalloc(sizeof(resinfo_T));
+ char *buf = (char *)zalloc(12);
+ snprintf(buf, 12, "UNKNOWN-%d", i);
+ info->res = - 1; /* negative value indicates "unknown" */
+ info->name = buf;
+ info->type = ZLIMTYPE_UNKNOWN;
+ info->unit = 1;
+ info->opt = 'N';
+ info->descr = buf;
+ resinfo[i] = info;
+ }
+ }
+}
+
+/**/
+static void
+free_resinfo(void)
+{
+ int i;
+ for (i=0; i<RLIM_NLIMITS; ++i) {
+ if (resinfo[i]->res < 0) { /* unknown resource */
+ free(resinfo[i]->name);
+ free((void*)resinfo[i]);
+ }
+ }
+ free(resinfo);
+ resinfo = NULL;
+}
+
+/* Find resource by its option character */
+
+/**/
+static int
+find_resource(char c)
+{
+ int i;
+ for (i=0; i<RLIM_NLIMITS; ++i) {
+ if (resinfo[i]->opt == c)
+ return i;
+ }
+ return -1;
+}
+
+/* Print a value of type rlim_t */
+
+/**/
+static void
+printrlim(rlim_t val, const char *unit)
+{
+# ifdef RLIM_T_IS_QUAD_T
+ printf("%qd%s", val, unit);
+# else
+# ifdef RLIM_T_IS_LONG_LONG
+ printf("%lld%s", val, unit);
+# else
+# ifdef RLIM_T_IS_UNSIGNED
+ printf("%lu%s", (unsigned long)val, unit);
+# else
+ printf("%ld%s", (long)val, unit);
+# endif /* RLIM_T_IS_UNSIGNED */
+# endif /* RLIM_T_IS_LONG_LONG */
+# endif /* RLIM_T_IS_QUAD_T */
+}
+
+/**/
static rlim_t
zstrtorlimt(const char *s, char **t, int base)
{
@@ -97,8 +287,8 @@ static void
showlimitvalue(int lim, rlim_t val)
{
/* display limit for resource number lim */
- if (lim < ZSH_NLIMITS)
- printf("%-16s", recs[lim]);
+ if (lim < RLIM_NLIMITS)
+ printf("%-16s", resinfo[lim]->name);
else
{
/* Unknown limit, hence unknown units. */
@@ -106,81 +296,25 @@ showlimitvalue(int lim, rlim_t val)
}
if (val == RLIM_INFINITY)
printf("unlimited\n");
- else if (lim >= ZSH_NLIMITS)
- {
-# ifdef RLIM_T_IS_QUAD_T
- printf("%qd\n", val);
-# else
-# ifdef RLIM_T_IS_LONG_LONG
- printf("%lld\n", val);
-# else
-# ifdef RLIM_T_IS_UNSIGNED
- printf("%lu\n", (unsigned long)val);
-# else
- printf("%ld\n", (long)val);
-# endif /* RLIM_T_IS_UNSIGNED */
-# endif /* RLIM_T_IS_LONG_LONG */
-# endif /* RLIM_T_IS_QUAD_T */
- }
- else if (limtype[lim] == ZLIMTYPE_TIME) {
+ else if (lim >= RLIM_NLIMITS)
+ printrlim(val, "\n");
+ else if (resinfo[lim]->type == ZLIMTYPE_TIME) {
/* time-type resource -- display as hours, minutes and
seconds. */
printf("%d:%02d:%02d\n", (int)(val / 3600),
(int)(val / 60) % 60, (int)(val % 60));
- } else if (limtype[lim] == ZLIMTYPE_MICROSECONDS) {
- /* microseconds */
-# ifdef RLIM_T_IS_QUAD_T
- printf("%qdus\n", val);
-# else
-# ifdef RLIM_T_IS_LONG_LONG
- printf("%lldus\n", val);
-# else
-# ifdef RLIM_T_IS_UNSIGNED
- printf("%luus\n", (unsigned long)val);
-# else
- printf("%ldus\n", (long)val);
-# endif /* RLIM_T_IS_UNSIGNED */
-# endif /* RLIM_T_IS_LONG_LONG */
-# endif /* RLIM_T_IS_QUAD_T */
- } else if (limtype[lim] == ZLIMTYPE_NUMBER ||
- limtype[lim] == ZLIMTYPE_UNKNOWN) {
- /* pure numeric resource */
-# ifdef RLIM_T_IS_QUAD_T
- printf("%qd\n", val);
-# else
-# ifdef RLIM_T_IS_LONG_LONG
- printf("%lld\n", val);
-# else
-# ifdef RLIM_T_IS_UNSIGNED
- printf("%lu\n", (unsigned long)val);
-# else
- printf("%ld\n", (long)val);
-# endif /* RLIM_T_IS_UNSIGNED */
-# endif /* RLIM_T_IS_LONG_LONG */
-# endif /* RLIM_T_IS_QUAD_T */
- } else if (val >= 1024L * 1024L)
- /* memory resource -- display with `K' or `M' modifier */
-# ifdef RLIM_T_IS_QUAD_T
- printf("%qdMB\n", val / (1024L * 1024L));
- else
- printf("%qdkB\n", val / 1024L);
-# else
-# ifdef RLIM_T_IS_LONG_LONG
- printf("%lldMB\n", val / (1024L * 1024L));
- else
- printf("%lldkB\n", val / 1024L);
-# else
-# ifdef RLIM_T_IS_UNSIGNED
- printf("%luMB\n", (unsigned long)(val / (1024L * 1024L)));
- else
- printf("%lukB\n", (unsigned long)(val / 1024L));
-# else
- printf("%ldMB\n", (long)val / (1024L * 1024L));
- else
- printf("%ldkB\n", (long)val / 1024L);
-# endif /* RLIM_T_IS_UNSIGNED */
-# endif /* RLIM_T_IS_LONG_LONG */
-# endif /* RLIM_T_IS_QUAD_T */
+ } else if (resinfo[lim]->type == ZLIMTYPE_MICROSECONDS)
+ printrlim(val, "us\n"); /* microseconds */
+ else if (resinfo[lim]->type == ZLIMTYPE_NUMBER ||
+ resinfo[lim]->type == ZLIMTYPE_UNKNOWN)
+ printrlim(val, "\n"); /* pure numeric resource */
+ else {
+ /* memory resource -- display with `k' or `M' modifier */
+ if (val >= 1024L * 1024L)
+ printrlim(val/(1024L * 1024L), "MB\n");
+ else
+ printrlim(val/1024L, "kB\n");
+ }
}
/* Display resource limits. hard indicates whether `hard' or `soft' *
@@ -193,7 +327,7 @@ showlimits(char *nam, int hard, int lim)
{
int rt;
- if (lim >= ZSH_NLIMITS)
+ if (lim >= RLIM_NLIMITS)
{
/*
* Not configured into the shell. Ask the OS
@@ -215,7 +349,7 @@ showlimits(char *nam, int hard, int lim)
else
{
/* main loop over resource types */
- for (rt = 0; rt != ZSH_NLIMITS; rt++)
+ for (rt = 0; rt != RLIM_NLIMITS; rt++)
showlimitvalue(rt, (hard) ? limits[rt].rlim_max :
limits[rt].rlim_cur);
}
@@ -234,7 +368,7 @@ printulimit(char *nam, int lim, int hard, int head)
rlim_t limit;
/* get the limit in question */
- if (lim >= ZSH_NLIMITS)
+ if (lim >= RLIM_NLIMITS)
{
struct rlimit vals;
@@ -248,199 +382,25 @@ printulimit(char *nam, int lim, int hard, int head)
else
limit = (hard) ? limits[lim].rlim_max : limits[lim].rlim_cur;
/* display the appropriate heading */
- switch (lim) {
- case RLIMIT_CORE:
- if (head)
- printf("-c: core file size (blocks) ");
- if (limit != RLIM_INFINITY)
- limit /= 512;
- break;
- case RLIMIT_DATA:
- if (head)
- printf("-d: data seg size (kbytes) ");
- if (limit != RLIM_INFINITY)
- limit /= 1024;
- break;
- case RLIMIT_FSIZE:
- if (head)
- printf("-f: file size (blocks) ");
- if (limit != RLIM_INFINITY)
- limit /= 512;
- break;
-# ifdef HAVE_RLIMIT_SIGPENDING
- case RLIMIT_SIGPENDING:
- if (head)
- printf("-i: pending signals ");
- break;
-# endif
-# ifdef HAVE_RLIMIT_MEMLOCK
- case RLIMIT_MEMLOCK:
- if (head)
- printf("-l: locked-in-memory size (kbytes) ");
- if (limit != RLIM_INFINITY)
- limit /= 1024;
- break;
-# endif /* HAVE_RLIMIT_MEMLOCK */
-/* If RLIMIT_VMEM and RLIMIT_RSS are defined and equal, avoid *
- * duplicate case statement. Observed on QNX Neutrino 6.1.0. */
-# if defined(HAVE_RLIMIT_RSS) && !defined(RLIMIT_VMEM_IS_RSS) && !defined(RLIMIT_RSS_IS_AS)
- case RLIMIT_RSS:
- if (head)
- printf("-m: resident set size (kbytes) ");
- if (limit != RLIM_INFINITY)
- limit /= 1024;
- break;
-# endif /* HAVE_RLIMIT_RSS */
-# if defined(HAVE_RLIMIT_VMEM) && defined(HAVE_RLIMIT_RSS) && defined(RLIMIT_VMEM_IS_RSS)
- case RLIMIT_VMEM:
- if (head)
- printf("-m: memory size (kbytes) ");
- if (limit != RLIM_INFINITY)
- limit /= 1024;
- break;
-# endif /* HAVE_RLIMIT_VMEM */
-# ifdef HAVE_RLIMIT_NOFILE
- case RLIMIT_NOFILE:
- if (head)
- printf("-n: file descriptors ");
- break;
-# endif /* HAVE_RLIMIT_NOFILE */
-# ifdef HAVE_RLIMIT_MSGQUEUE
- case RLIMIT_MSGQUEUE:
- if (head)
- printf("-q: bytes in POSIX msg queues ");
- break;
-# endif
- case RLIMIT_STACK:
- if (head)
- printf("-s: stack size (kbytes) ");
- if (limit != RLIM_INFINITY)
- limit /= 1024;
- break;
- case RLIMIT_CPU:
- if (head)
- printf("-t: cpu time (seconds) ");
- break;
-# ifdef HAVE_RLIMIT_NPROC
- case RLIMIT_NPROC:
- if (head)
- printf("-u: processes ");
- break;
-# endif /* HAVE_RLIMIT_NPROC */
-# if defined(HAVE_RLIMIT_VMEM) && (!defined(HAVE_RLIMIT_RSS) || !defined(RLIMIT_VMEM_IS_RSS))
- case RLIMIT_VMEM:
- if (head)
- printf("-v: virtual memory size (kbytes) ");
- if (limit != RLIM_INFINITY)
- limit /= 1024;
- break;
-# endif /* HAVE_RLIMIT_VMEM */
-# if defined HAVE_RLIMIT_AS && !defined(RLIMIT_VMEM_IS_AS)
- case RLIMIT_AS:
- if (head)
- printf("-v: address space (kbytes) ");
- if (limit != RLIM_INFINITY)
- limit /= 1024;
- break;
-# endif /* HAVE_RLIMIT_AS */
-# ifdef HAVE_RLIMIT_LOCKS
- case RLIMIT_LOCKS:
- if (head)
- printf("-x: file locks ");
- break;
-# endif /* HAVE_RLIMIT_LOCKS */
-# ifdef HAVE_RLIMIT_AIO_MEM
- case RLIMIT_AIO_MEM:
- if (head)
- printf("-N %2d: AIO locked-in-memory (kbytes)", RLIMIT_AIO_MEM);
- if (limit != RLIM_INFINITY)
- limit /= 1024;
- break;
-# endif /* HAVE_RLIMIT_AIO_MEM */
-# ifdef HAVE_RLIMIT_AIO_OPS
- case RLIMIT_AIO_OPS:
- if (head)
- printf("-N %2d: AIO operations ", RLIMIT_AIO_OPS);
- break;
-# endif /* HAVE_RLIMIT_AIO_OPS */
-# ifdef HAVE_RLIMIT_TCACHE
- case RLIMIT_TCACHE:
- if (head)
- printf("-N %2d: cached threads ", RLIMIT_TCACHE);
- break;
-# endif /* HAVE_RLIMIT_TCACHE */
-# ifdef HAVE_RLIMIT_SBSIZE
- case RLIMIT_SBSIZE:
- if (head)
- printf("-b: socket buffer size (bytes) ");
- break;
-# endif /* HAVE_RLIMIT_SBSIZE */
-# ifdef HAVE_RLIMIT_PTHREAD
- case RLIMIT_PTHREAD:
- if (head)
- printf("%s", THREAD_FMT);
- break;
-# endif /* HAVE_RLIMIT_PTHREAD */
-# ifdef HAVE_RLIMIT_NICE
- case RLIMIT_NICE:
- if (head)
- printf("-e: max nice ");
- break;
-# endif /* HAVE_RLIMIT_NICE */
-# ifdef HAVE_RLIMIT_RTPRIO
- case RLIMIT_RTPRIO:
- if (head)
- printf("-r: max rt priority ");
- break;
-# endif /* HAVE_RLIMIT_RTPRIO */
-# ifdef HAVE_RLIMIT_NPTS
- case RLIMIT_NPTS:
- if (head)
- printf("-p: pseudo-terminals ");
- break;
-# endif /* HAVE_RLIMIT_NPTS */
-# ifdef HAVE_RLIMIT_SWAP
- case RLIMIT_SWAP:
- if (head)
- printf("-w: swap size (kbytes) ");
- if (limit != RLIM_INFINITY)
- limit /= 1024;
- break;
-# endif /* HAVE_RLIMIT_SWAP */
-# ifdef HAVE_RLIMIT_KQUEUES
- case RLIMIT_KQUEUES:
- if (head)
- printf("-k: kqueues ");
- break;
-# endif /* HAVE_RLIMIT_KQUEUES */
-# ifdef HAVE_RLIMIT_UMTXP
- case RLIMIT_UMTXP:
- if (head)
- printf("-o: umtx shared locks ");
- break;
-# endif /* HAVE_RLIMIT_UMTXP */
- default:
- if (head)
- printf("-N %2d: ", lim);
- break;
+ if (head) {
+ if (lim < RLIM_NLIMITS) {
+ const resinfo_T *info = resinfo[lim];
+ if (info->opt == 'N')
+ printf("-N %2d: %-29s", lim, info->descr);
+ else
+ printf("-%c: %-32s", info->opt, info->descr);
+ }
+ else
+ printf("-N %2d: %-29s", lim, "");
}
/* display the limit */
if (limit == RLIM_INFINITY)
printf("unlimited\n");
else {
-# ifdef RLIM_T_IS_QUAD_T
- printf("%qd\n", limit);
-# else
-# ifdef RLIM_T_IS_LONG_LONG
- printf("%lld\n", limit);
-# else
-# ifdef RLIM_T_IS_UNSIGNED
- printf("%lu\n", (unsigned long)limit);
-# else
- printf("%ld\n", (long)limit);
-# endif /* RLIM_T_IS_UNSIGNED */
-# endif /* RLIM_T_IS_LONG_LONG */
-# endif /* RLIM_T_IS_QUAD_T */
+ if (lim < RLIM_NLIMITS)
+ printrlim(limit/resinfo[lim]->unit, "\n");
+ else
+ printrlim(limit, "\n");
}
return 0;
@@ -450,7 +410,7 @@ printulimit(char *nam, int lim, int hard, int head)
static int
do_limit(char *nam, int lim, rlim_t val, int hard, int soft, int set)
{
- if (lim >= ZSH_NLIMITS) {
+ if (lim >= RLIM_NLIMITS) {
struct rlimit vals;
if (getrlimit(lim, &vals) < 0)
{
@@ -558,8 +518,8 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func))
lim = (int)zstrtol(s, NULL, 10);
}
else
- for (lim = -1, limnum = 0; limnum < ZSH_NLIMITS; limnum++)
- if (!strncmp(recs[limnum], s, strlen(s))) {
+ for (lim = -1, limnum = 0; limnum < RLIM_NLIMITS; limnum++)
+ if (!strncmp(resinfo[limnum]->name, s, strlen(s))) {
if (lim != -1)
lim = -2;
else
@@ -576,7 +536,7 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func))
/* without value for limit, display the current limit */
if (!(s = *argv++))
return showlimits(nam, hard, lim);
- if (lim >= ZSH_NLIMITS)
+ if (lim >= RLIM_NLIMITS)
{
val = zstrtorlimt(s, &s, 10);
if (*s)
@@ -586,7 +546,7 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func))
return 1;
}
}
- else if (limtype[lim] == ZLIMTYPE_TIME) {
+ else if (resinfo[lim]->type == ZLIMTYPE_TIME) {
/* time-type resource -- may be specified as seconds, or minutes or *
* hours with the `m' and `h' modifiers, and `:' may be used to add *
* together more than one of these. It's easier to understand from *
@@ -604,9 +564,9 @@ bin_limit(char *nam, char **argv, Options ops, UNUSED(int func))
return 1;
}
}
- } else if (limtype[lim] == ZLIMTYPE_NUMBER ||
- limtype[lim] == ZLIMTYPE_UNKNOWN ||
- limtype[lim] == ZLIMTYPE_MICROSECONDS) {
+ } else if (resinfo[lim]->type == ZLIMTYPE_NUMBER ||
+ resinfo[lim]->type == ZLIMTYPE_UNKNOWN ||
+ resinfo[lim]->type == ZLIMTYPE_MICROSECONDS) {
/* pure numeric resource -- only a straight decimal number is
permitted. */
char *t = s;
@@ -642,7 +602,7 @@ static int
do_unlimit(char *nam, int lim, int hard, int soft, int set, int euid)
{
/* remove specified limit */
- if (lim >= ZSH_NLIMITS) {
+ if (lim >= RLIM_NLIMITS) {
struct rlimit vals;
if (getrlimit(lim, &vals) < 0)
{
@@ -718,8 +678,8 @@ bin_unlimit(char *nam, char **argv, Options ops, UNUSED(int func))
if (idigit(**argv)) {
lim = (int)zstrtol(*argv, NULL, 10);
} else {
- for (lim = -1, limnum = 0; limnum < ZSH_NLIMITS; limnum++)
- if (!strncmp(recs[limnum], *argv, strlen(*argv))) {
+ for (lim = -1, limnum = 0; limnum < RLIM_NLIMITS; limnum++)
+ if (!strncmp(resinfo[limnum]->name, *argv, strlen(*argv))) {
if (lim != -1)
lim = -2;
else
@@ -800,116 +760,14 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
resmask = (1 << RLIM_NLIMITS) - 1;
nres = RLIM_NLIMITS;
continue;
- case 't':
- res = RLIMIT_CPU;
- break;
- case 'f':
- res = RLIMIT_FSIZE;
- break;
- case 'd':
- res = RLIMIT_DATA;
- break;
- case 's':
- res = RLIMIT_STACK;
- break;
- case 'c':
- res = RLIMIT_CORE;
- break;
-# ifdef HAVE_RLIMIT_SBSIZE
- case 'b':
- res = RLIMIT_SBSIZE;
- break;
-# endif /* HAVE_RLIMIT_SBSIZE */
-# ifdef HAVE_RLIMIT_MEMLOCK
- case 'l':
- res = RLIMIT_MEMLOCK;
- break;
-# endif /* HAVE_RLIMIT_MEMLOCK */
-# ifdef HAVE_RLIMIT_RSS
- case 'm':
- res = RLIMIT_RSS;
- break;
-# endif /* HAVE_RLIMIT_RSS */
-# ifdef HAVE_RLIMIT_NOFILE
- case 'n':
- res = RLIMIT_NOFILE;
- break;
-# endif /* HAVE_RLIMIT_NOFILE */
-# ifdef HAVE_RLIMIT_NPROC
- case 'u':
- res = RLIMIT_NPROC;
- break;
-# endif /* HAVE_RLIMIT_NPROC */
-# if defined(HAVE_RLIMIT_VMEM) || defined(HAVE_RLIMIT_AS)
- case 'v':
-# ifdef HAVE_RLIMIT_VMEM
- res = RLIMIT_VMEM;
-# else
- res = RLIMIT_AS;
-# endif
- break;
-# endif /* HAVE_RLIMIT_VMEM */
-# ifdef HAVE_RLIMIT_LOCKS
- case 'x':
- res = RLIMIT_LOCKS;
- break;
-# endif
-# ifdef HAVE_RLIMIT_SIGPENDING
- case 'i':
- res = RLIMIT_SIGPENDING;
- break;
-# endif
-# ifdef HAVE_RLIMIT_MSGQUEUE
- case 'q':
- res = RLIMIT_MSGQUEUE;
- break;
-# endif
-# ifdef HAVE_RLIMIT_NICE
- case 'e':
- res = RLIMIT_NICE;
- break;
-# endif
-# ifdef HAVE_RLIMIT_RTPRIO
- case 'r':
- res = RLIMIT_RTPRIO;
- break;
-# else
-# ifdef HAVE_RLIMIT_NTHR
- /* For compatibility with sh on NetBSD */
- case 'r':
- res = RLIMIT_NTHR;
- break;
-# endif /* HAVE_RLIMIT_NTHR */
-# endif
-# ifdef HAVE_RLIMIT_NPTS
- case 'p':
- res = RLIMIT_NPTS;
- break;
-# endif
-# ifdef HAVE_RLIMIT_SWAP
- case 'w':
- res = RLIMIT_SWAP;
- break;
-# endif
-# ifdef HAVE_RLIMIT_KQUEUES
- case 'k':
- res = RLIMIT_KQUEUES;
- break;
-# endif
-# ifdef HAVE_RLIMIT_PTHREAD
- case 'T':
- res = RLIMIT_PTHREAD;
- break;
-# endif
-# ifdef HAVE_RLIMIT_UMTXP
- case 'o':
- res = RLIMIT_UMTXP;
- break;
-# endif
default:
- /* unrecognised limit */
- zwarnnam(name, "bad option: -%c", *options);
- return 1;
+ res = find_resource(*options);
+ if (res < 0) {
+ /* unrecognised limit */
+ zwarnnam(name, "bad option: -%c", *options);
+ return 1;
+ }
+ break;
}
if (options[1]) {
resmask |= 1 << res;
@@ -961,34 +819,8 @@ bin_ulimit(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
return 1;
}
/* scale appropriately */
- switch (res) {
- case RLIMIT_FSIZE:
- case RLIMIT_CORE:
- limit *= 512;
- break;
- case RLIMIT_DATA:
- case RLIMIT_STACK:
-# ifdef HAVE_RLIMIT_RSS
- case RLIMIT_RSS:
-# endif /* HAVE_RLIMIT_RSS */
-# ifdef HAVE_RLIMIT_MEMLOCK
- case RLIMIT_MEMLOCK:
-# endif /* HAVE_RLIMIT_MEMLOCK */
-/* If RLIMIT_VMEM and RLIMIT_RSS are defined and equal, avoid *
- * duplicate case statement. Observed on QNX Neutrino 6.1.0. */
-# if defined(HAVE_RLIMIT_VMEM) && !defined(RLIMIT_VMEM_IS_RSS)
- case RLIMIT_VMEM:
-# endif /* HAVE_RLIMIT_VMEM */
-/* ditto RLIMIT_VMEM and RLIMIT_AS */
-# if defined(HAVE_RLIMIT_AS) && !defined(RLIMIT_VMEM_IS_AS) && !defined(RLIMIT_RSS_IS_AS)
- case RLIMIT_AS:
-# endif /* HAVE_RLIMIT_AS */
-# ifdef HAVE_RLIMIT_AIO_MEM
- case RLIMIT_AIO_MEM:
-# endif /* HAVE_RLIMIT_AIO_MEM */
- limit *= 1024;
- break;
- }
+ if (res < RLIM_NLIMITS)
+ limit *= resinfo[res]->unit;
}
if (do_limit(name, res, limit, hard, soft, 1))
ret++;
@@ -1052,6 +884,7 @@ enables_(Module m, int **enables)
int
boot_(UNUSED(Module m))
{
+ set_resinfo();
return 0;
}
@@ -1059,6 +892,7 @@ boot_(UNUSED(Module m))
int
cleanup_(Module m)
{
+ free_resinfo();
return setfeatureenables(m, &module_features, NULL);
}