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