1*cf5a6c84SAndroid Build Coastguard Worker /* ulimit.c - Modify resource limits
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2015 Rob Landley <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker *
5*cf5a6c84SAndroid Build Coastguard Worker * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ulimit.html
6*cf5a6c84SAndroid Build Coastguard Worker * And man prlimit(2).
7*cf5a6c84SAndroid Build Coastguard Worker *
8*cf5a6c84SAndroid Build Coastguard Worker * Deviations from posix: The units on -f are supposed to be 512 byte
9*cf5a6c84SAndroid Build Coastguard Worker * "blocks" (no other options are specified, and even hard drives don't
10*cf5a6c84SAndroid Build Coastguard Worker * do that anymore). Bash uses 1024 byte blocks, so they don't care either.
11*cf5a6c84SAndroid Build Coastguard Worker * We consistently use bytes everywhere we can.
12*cf5a6c84SAndroid Build Coastguard Worker *
13*cf5a6c84SAndroid Build Coastguard Worker * Deviations from bash: Sizes are in bytes (instead of -p 512 and -f 1024).
14*cf5a6c84SAndroid Build Coastguard Worker * Bash's -p value has been wrong since 2010 (git 35f3d14dbbc5).
15*cf5a6c84SAndroid Build Coastguard Worker * The kernel implementation of RLIMIT_LOCKS (-x) was removed from Linux in
16*cf5a6c84SAndroid Build Coastguard Worker * 2003. Bash never implemented -b (it's in the help but unrecognized at
17*cf5a6c84SAndroid Build Coastguard Worker * runtime). We support -P to affect processes other than us.
18*cf5a6c84SAndroid Build Coastguard Worker
19*cf5a6c84SAndroid Build Coastguard Worker USE_ULIMIT(NEWTOY(ulimit, ">1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]", TOYFLAG_USR|TOYFLAG_BIN))
20*cf5a6c84SAndroid Build Coastguard Worker USE_ULIMIT(OLDTOY(prlimit, ulimit, TOYFLAG_USR|TOYFLAG_BIN))
21*cf5a6c84SAndroid Build Coastguard Worker
22*cf5a6c84SAndroid Build Coastguard Worker config ULIMIT
23*cf5a6c84SAndroid Build Coastguard Worker bool "ulimit"
24*cf5a6c84SAndroid Build Coastguard Worker default y
25*cf5a6c84SAndroid Build Coastguard Worker help
26*cf5a6c84SAndroid Build Coastguard Worker usage: ulimit [-P PID] [-SHRacdefilmnpqrstuv] [LIMIT]
27*cf5a6c84SAndroid Build Coastguard Worker
28*cf5a6c84SAndroid Build Coastguard Worker Print or set resource limits for process number PID. If no LIMIT specified
29*cf5a6c84SAndroid Build Coastguard Worker (or read-only -ap selected) display current value (sizes in bytes).
30*cf5a6c84SAndroid Build Coastguard Worker Default is ulimit -P $PPID -Sf" (show soft filesize of your shell).
31*cf5a6c84SAndroid Build Coastguard Worker
32*cf5a6c84SAndroid Build Coastguard Worker -P PID to affect (default $PPID) -a Show all limits
33*cf5a6c84SAndroid Build Coastguard Worker -S Set/show soft limit -H Set/show hard (maximum) limit
34*cf5a6c84SAndroid Build Coastguard Worker
35*cf5a6c84SAndroid Build Coastguard Worker -c Core file size (blocks) -d Process data segment (KiB)
36*cf5a6c84SAndroid Build Coastguard Worker -e Max scheduling priority -f File size (KiB)
37*cf5a6c84SAndroid Build Coastguard Worker -i Pending signal count -l Locked memory (KiB)
38*cf5a6c84SAndroid Build Coastguard Worker -m Resident Set Size (KiB) -n Number of open files
39*cf5a6c84SAndroid Build Coastguard Worker -p Pipe buffer (512 bytes) -q POSIX message queues
40*cf5a6c84SAndroid Build Coastguard Worker -r Max realtime priority -R Realtime latency (us)
41*cf5a6c84SAndroid Build Coastguard Worker -s Stack size (KiB) -t Total CPU time (s)
42*cf5a6c84SAndroid Build Coastguard Worker -u Maximum processes (this UID) -v Virtual memory size (KiB)
43*cf5a6c84SAndroid Build Coastguard Worker */
44*cf5a6c84SAndroid Build Coastguard Worker
45*cf5a6c84SAndroid Build Coastguard Worker #define FOR_ulimit
46*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
47*cf5a6c84SAndroid Build Coastguard Worker
48*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
49*cf5a6c84SAndroid Build Coastguard Worker long P;
50*cf5a6c84SAndroid Build Coastguard Worker )
51*cf5a6c84SAndroid Build Coastguard Worker
52*cf5a6c84SAndroid Build Coastguard Worker // This is a linux kernel syscall added in 2.6.36 (git c022a0acad53) which
53*cf5a6c84SAndroid Build Coastguard Worker // glibc only exports a wrapper prototype for if you #define _FSF_HURD_RULZE.
54*cf5a6c84SAndroid Build Coastguard Worker int prlimit(pid_t pid, int resource, const struct rlimit *new_limit,
55*cf5a6c84SAndroid Build Coastguard Worker struct rlimit *old_limit);
56*cf5a6c84SAndroid Build Coastguard Worker
57*cf5a6c84SAndroid Build Coastguard Worker // I'd like to sort the RLIMIT values 0-15, but mips, alpha and sparc
58*cf5a6c84SAndroid Build Coastguard Worker // override the asm-generic values for 5-9, and alphabetical order is nice for
59*cf5a6c84SAndroid Build Coastguard Worker // humans anyway.
ulimit_main(void)60*cf5a6c84SAndroid Build Coastguard Worker void ulimit_main(void)
61*cf5a6c84SAndroid Build Coastguard Worker {
62*cf5a6c84SAndroid Build Coastguard Worker struct rlimit rr;
63*cf5a6c84SAndroid Build Coastguard Worker int i;
64*cf5a6c84SAndroid Build Coastguard Worker // map and desc are in the same order as flags.
65*cf5a6c84SAndroid Build Coastguard Worker // The Linux kernel implementation of RLIMIT_LOCKS (-x) was removed in 2003.
66*cf5a6c84SAndroid Build Coastguard Worker char *flags="cdefilmnpqRrstuv";
67*cf5a6c84SAndroid Build Coastguard Worker char map[] = {RLIMIT_CORE, RLIMIT_DATA, RLIMIT_NICE,
68*cf5a6c84SAndroid Build Coastguard Worker RLIMIT_FSIZE, RLIMIT_SIGPENDING, RLIMIT_MEMLOCK,
69*cf5a6c84SAndroid Build Coastguard Worker RLIMIT_RSS, RLIMIT_NOFILE, 0, RLIMIT_MSGQUEUE,
70*cf5a6c84SAndroid Build Coastguard Worker RLIMIT_RTTIME, RLIMIT_RTPRIO, RLIMIT_STACK, RLIMIT_CPU, RLIMIT_NPROC,
71*cf5a6c84SAndroid Build Coastguard Worker RLIMIT_AS};
72*cf5a6c84SAndroid Build Coastguard Worker char *desc[]={"core dump size (blocks)", "data size (KiB)", "max nice",
73*cf5a6c84SAndroid Build Coastguard Worker "file size (blocks)", "pending signals", "locked memory (KiB)",
74*cf5a6c84SAndroid Build Coastguard Worker "RSS (KiB)", "open files", "pipe size (512 bytes)", "message queues",
75*cf5a6c84SAndroid Build Coastguard Worker "RT time (us)", "RT priority", "stack (KiB)", "cpu time (s)", "processes",
76*cf5a6c84SAndroid Build Coastguard Worker "address space (KiB)"};
77*cf5a6c84SAndroid Build Coastguard Worker
78*cf5a6c84SAndroid Build Coastguard Worker if (!(toys.optflags&(FLAG_H-1))) toys.optflags |= FLAG_f;
79*cf5a6c84SAndroid Build Coastguard Worker if ((FLAG(a)||FLAG(p)) && toys.optc) error_exit("can't set -ap");
80*cf5a6c84SAndroid Build Coastguard Worker
81*cf5a6c84SAndroid Build Coastguard Worker // Fetch data
82*cf5a6c84SAndroid Build Coastguard Worker if (!FLAG(P)) TT.P = getppid();
83*cf5a6c84SAndroid Build Coastguard Worker
84*cf5a6c84SAndroid Build Coastguard Worker for (i=0; i<sizeof(map); i++) {
85*cf5a6c84SAndroid Build Coastguard Worker int get = toys.optflags&(FLAG_a|(1<<i));
86*cf5a6c84SAndroid Build Coastguard Worker
87*cf5a6c84SAndroid Build Coastguard Worker if (get && prlimit(TT.P, map[i], 0, &rr)) perror_exit("-%c", flags[i]);
88*cf5a6c84SAndroid Build Coastguard Worker if (!toys.optc) {
89*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(a)) printf("-%c: %-25s ", flags[i], desc[i]);
90*cf5a6c84SAndroid Build Coastguard Worker if (get) {
91*cf5a6c84SAndroid Build Coastguard Worker if ((1<<i)&FLAG_p) {
92*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(H))
93*cf5a6c84SAndroid Build Coastguard Worker xreadfile("/proc/sys/fs/pipe-max-size", toybuf, sizeof(toybuf));
94*cf5a6c84SAndroid Build Coastguard Worker else {
95*cf5a6c84SAndroid Build Coastguard Worker int pp[2];
96*cf5a6c84SAndroid Build Coastguard Worker
97*cf5a6c84SAndroid Build Coastguard Worker xpipe(pp);
98*cf5a6c84SAndroid Build Coastguard Worker sprintf(toybuf, "%d\n", fcntl(*pp, F_GETPIPE_SZ));
99*cf5a6c84SAndroid Build Coastguard Worker }
100*cf5a6c84SAndroid Build Coastguard Worker printf("%s", toybuf);
101*cf5a6c84SAndroid Build Coastguard Worker } else {
102*cf5a6c84SAndroid Build Coastguard Worker rlim_t rl = FLAG(H) ? rr.rlim_max : rr.rlim_cur;
103*cf5a6c84SAndroid Build Coastguard Worker
104*cf5a6c84SAndroid Build Coastguard Worker if (rl == RLIM_INFINITY) printf("unlimited\n");
105*cf5a6c84SAndroid Build Coastguard Worker else printf("%ld\n", (long)rl);
106*cf5a6c84SAndroid Build Coastguard Worker }
107*cf5a6c84SAndroid Build Coastguard Worker }
108*cf5a6c84SAndroid Build Coastguard Worker }
109*cf5a6c84SAndroid Build Coastguard Worker if (toys.optflags&(1<<i)) break;
110*cf5a6c84SAndroid Build Coastguard Worker }
111*cf5a6c84SAndroid Build Coastguard Worker
112*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(a)||FLAG(p)) return;
113*cf5a6c84SAndroid Build Coastguard Worker
114*cf5a6c84SAndroid Build Coastguard Worker if (toys.optc) {
115*cf5a6c84SAndroid Build Coastguard Worker rlim_t val;
116*cf5a6c84SAndroid Build Coastguard Worker
117*cf5a6c84SAndroid Build Coastguard Worker if (tolower(**toys.optargs) == 'u') val = RLIM_INFINITY;
118*cf5a6c84SAndroid Build Coastguard Worker else val = atolx_range(*toys.optargs, 0, LONG_MAX);
119*cf5a6c84SAndroid Build Coastguard Worker
120*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(H)) rr.rlim_max = val;
121*cf5a6c84SAndroid Build Coastguard Worker else rr.rlim_cur = val;
122*cf5a6c84SAndroid Build Coastguard Worker if (prlimit(TT.P, map[i], &rr, 0)) perror_exit(0);
123*cf5a6c84SAndroid Build Coastguard Worker }
124*cf5a6c84SAndroid Build Coastguard Worker }
125