12f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley/* ulimit.c - Modify resource limits 22f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * 32f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * Copyright 2015 Rob Landley <rob@landley.net> 42f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * 52f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ulimit.html 62f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * And man prlimit(2). 72f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * 82f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * Deviations from posix: The units on -f are supposed to be 512 byte 92f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * "blocks" (no other options are specified, and even hard drives don't 102f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * do that anymore). Bash uses 1024 byte blocks, so they don't care either. 112f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * We consistently use bytes everywhere we can. 122f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * 132f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * Deviations from bash: Sizes are in bytes (instead of -p 512 and -f 1024). 142f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * Bash's -p value has been wrong since 2010 (git 35f3d14dbbc5). 152f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * The kernel implementation of RLIMIT_LOCKS (-x) was removed from Linux in 162f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * 2003. Bash never implemented -b (it's in the help but unrecognized at 172f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley * runtime). We support -P to affect processes other than us. 182f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 192f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob LandleyUSE_ULIMIT(NEWTOY(ulimit, ">1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]", TOYFLAG_USR|TOYFLAG_BIN)) 202f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 212f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landleyconfig ULIMIT 222f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley bool "ulimit" 232f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley default y 242f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley help 252f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley usage: ulimit [-P PID] [-SHRacdefilmnpqrstuv] [LIMIT] 262f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 272f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley Print or set resource limits for process number PID. If no LIMIT specified 282f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley (or read-only -ap selected) display current value (sizes in bytes). 292f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley Default is ulimit -P $PPID -Sf" (show soft filesize of your shell). 302f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 312f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley -S Set/show soft limit -H Set/show hard (maximum) limit 322f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley -a Show all limits -c Core file size 332f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley -d Process data segment -e Max scheduling priority 342f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley -f Output file size -i Pending signal count 352f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley -l Locked memory -m Resident Set Size 362f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley -n Number of open files -p Pipe buffer 372f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley -q Posix message queue -r Max Real-time priority 382f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley -R Realtime latency (usec) -s Stack size 392f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley -t Total CPU time (in seconds) -u Maximum processes (under this UID) 402f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley -v Virtual memory size -P PID to affect (default $PPID) 412f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley*/ 422f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 432f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley#define FOR_ulimit 442f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley#include "toys.h" 452f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 462f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob LandleyGLOBALS( 472f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley long pid; 482f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley) 492f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 502f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley// This is a linux kernel syscall added in 2.6.36 (git c022a0acad53) which 512f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley// glibc only exports a wrapper prototype for if you #define _FSF_HURD_RULZE. 522f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landleyint prlimit(pid_t pid, int resource, const struct rlimit *new_limit, 532f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley struct rlimit *old_limit); 542f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 552f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley// I'd like to sort the RLIMIT values 0-15, but mips, alpha and sparc 562f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley// override the asm-generic values for 5-9. Also, the kernel implementation 572f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley// of RLIMIT_LOCKS (-x) was removed from Linux in 2003. 582f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landleyvoid ulimit_main(void) 592f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley{ 602f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley struct rlimit rr; 612f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley int i; 622f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley // Order is cdefilmnqRrstuv 632f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley char map[] = {RLIMIT_CORE, RLIMIT_DATA, RLIMIT_NICE, RLIMIT_FSIZE, 642f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley RLIMIT_SIGPENDING, RLIMIT_MEMLOCK, RLIMIT_RSS, RLIMIT_NOFILE, 0, 652f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley RLIMIT_MSGQUEUE, RLIMIT_RTTIME, RLIMIT_RTPRIO, RLIMIT_STACK, 662f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley RLIMIT_CPU, RLIMIT_NPROC, RLIMIT_AS}; 672f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 682f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (!(toys.optflags&(FLAG_H-1))) toys.optflags |= FLAG_f; 692f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if ((toys.optflags&(FLAG_a|FLAG_p)) && toys.optc) error_exit("can't set -ap"); 702f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 712f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley // Fetch data 722f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (!(toys.optflags&FLAG_P)) TT.pid = getppid(); 732f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 742f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley for (i=0; i<sizeof(map); i++) { 752f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley char *flags="cdefilmnpqRrstuv"; 762f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 772f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley int get = toys.optflags&(FLAG_a|(1<<i)); 782f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 792f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (get && prlimit(TT.pid, map[i], 0, &rr)) perror_exit("-%c", flags[i]); 802f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (!toys.optc) { 812f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (toys.optflags&FLAG_a) printf("-%c: ", flags[i]); 822f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (get) { 832f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if ((1<<i)&FLAG_p) { 842f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (toys.optflags&FLAG_H) 852f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley xreadfile("/proc/sys/fs/pipe-max-size", toybuf, sizeof(toybuf)); 862f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley else { 872f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley int pp[2]; 882f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 892f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley xpipe(pp); 902f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley sprintf(toybuf, "%d\n", fcntl(*pp, F_GETPIPE_SZ)); 912f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley } 922f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley printf("%s", toybuf); 932f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley } else { 942f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley rlim_t rl = (toys.optflags&FLAG_H) ? rr.rlim_max : rr.rlim_cur; 952f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 962f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (rl == RLIM_INFINITY) printf("unlimited\n"); 972f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley else printf("%ld\n", (long)rl); 982f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley } 992f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley } 1002f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley } 1012f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (toys.optflags&(1<<i)) break; 1022f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley } 1032f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 1042f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (toys.optflags&(FLAG_a|FLAG_p)) return; 1052f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 1062f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (toys.optc) { 1072f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley rlim_t val; 1082f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 1092f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (tolower(**toys.optargs == 'i')) val = RLIM_INFINITY; 1102f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley else val = atolx_range(*toys.optargs, 0, LONG_MAX); 1112f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley 1122f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (toys.optflags&FLAG_H) rr.rlim_max = val; 1132f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley else rr.rlim_cur = val; 1142f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley if (prlimit(TT.pid, map[i], &rr, 0)) perror_exit(0); 1152f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley } 1162f3f26ea1ec581cd24a0778323eb0844f03fd6a3Rob Landley} 117