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