ulimit.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* ulimit.c - Modify resource limits
  2. *
  3. * Copyright 2015 Rob Landley <rob@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. USE_ULIMIT(NEWTOY(ulimit, ">1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]", TOYFLAG_USR|TOYFLAG_BIN))
  19. USE_ULIMIT(OLDTOY(prlimit, ulimit, TOYFLAG_USR|TOYFLAG_BIN))
  20. config ULIMIT
  21. bool "ulimit"
  22. default y
  23. depends on TOYBOX_PRLIMIT
  24. help
  25. usage: ulimit [-P PID] [-SHRacdefilmnpqrstuv] [LIMIT]
  26. Print or set resource limits for process number PID. If no LIMIT specified
  27. (or read-only -ap selected) display current value (sizes in bytes).
  28. Default is ulimit -P $PPID -Sf" (show soft filesize of your shell).
  29. -P PID to affect (default $PPID) -a Show all limits
  30. -S Set/show soft limit -H Set/show hard (maximum) limit
  31. -c Core file size (blocks) -d Process data segment (KiB)
  32. -e Max scheduling priority -f File size (KiB)
  33. -i Pending signal count -l Locked memory (KiB)
  34. -m Resident Set Size (KiB) -n Number of open files
  35. -p Pipe buffer (512 bytes) -q POSIX message queues
  36. -r Max realtime priority -R Realtime latency (us)
  37. -s Stack size (KiB) -t Total CPU time (s)
  38. -u Maximum processes (this UID) -v Virtual memory size (KiB)
  39. */
  40. #define FOR_ulimit
  41. #include "toys.h"
  42. GLOBALS(
  43. long P;
  44. )
  45. // This is a linux kernel syscall added in 2.6.36 (git c022a0acad53) which
  46. // glibc only exports a wrapper prototype for if you #define _FSF_HURD_RULZE.
  47. int prlimit(pid_t pid, int resource, const struct rlimit *new_limit,
  48. struct rlimit *old_limit);
  49. // I'd like to sort the RLIMIT values 0-15, but mips, alpha and sparc
  50. // override the asm-generic values for 5-9, and alphabetical order is nice for
  51. // humans anyway.
  52. void ulimit_main(void)
  53. {
  54. struct rlimit rr;
  55. int i;
  56. // map and desc are in the same order as flags.
  57. // The Linux kernel implementation of RLIMIT_LOCKS (-x) was removed in 2003.
  58. char *flags="cdefilmnpqRrstuv";
  59. char map[] = {RLIMIT_CORE, RLIMIT_DATA, RLIMIT_NICE,
  60. RLIMIT_FSIZE, RLIMIT_SIGPENDING, RLIMIT_MEMLOCK,
  61. RLIMIT_RSS, RLIMIT_NOFILE, 0, RLIMIT_MSGQUEUE,
  62. RLIMIT_RTTIME, RLIMIT_RTPRIO, RLIMIT_STACK, RLIMIT_CPU, RLIMIT_NPROC,
  63. RLIMIT_AS};
  64. char *desc[]={"core dump size (blocks)", "data size (KiB)", "max nice",
  65. "file size (blocks)", "pending signals", "locked memory (KiB)",
  66. "RSS (KiB)", "open files", "pipe size (512 bytes)", "message queues",
  67. "RT time (us)", "RT priority", "stack (KiB)", "cpu time (s)", "processes",
  68. "address space (KiB)"};
  69. if (!(toys.optflags&(FLAG_H-1))) toys.optflags |= FLAG_f;
  70. if ((FLAG(a)||FLAG(p)) && toys.optc) error_exit("can't set -ap");
  71. // Fetch data
  72. if (!FLAG(P)) TT.P = getppid();
  73. for (i=0; i<sizeof(map); i++) {
  74. int get = toys.optflags&(FLAG_a|(1<<i));
  75. if (get && prlimit(TT.P, map[i], 0, &rr)) perror_exit("-%c", flags[i]);
  76. if (!toys.optc) {
  77. if (FLAG(a)) printf("-%c: %-25s ", flags[i], desc[i]);
  78. if (get) {
  79. if ((1<<i)&FLAG_p) {
  80. if (FLAG(H))
  81. xreadfile("/proc/sys/fs/pipe-max-size", toybuf, sizeof(toybuf));
  82. else {
  83. int pp[2];
  84. xpipe(pp);
  85. sprintf(toybuf, "%d\n", fcntl(*pp, F_GETPIPE_SZ));
  86. }
  87. printf("%s", toybuf);
  88. } else {
  89. rlim_t rl = FLAG(H) ? rr.rlim_max : rr.rlim_cur;
  90. if (rl == RLIM_INFINITY) printf("unlimited\n");
  91. else printf("%ld\n", (long)rl);
  92. }
  93. }
  94. }
  95. if (toys.optflags&(1<<i)) break;
  96. }
  97. if (FLAG(a)||FLAG(p)) return;
  98. if (toys.optc) {
  99. rlim_t val;
  100. if (tolower(**toys.optargs) == 'u') val = RLIM_INFINITY;
  101. else val = atolx_range(*toys.optargs, 0, LONG_MAX);
  102. if (FLAG(H)) rr.rlim_max = val;
  103. else rr.rlim_cur = val;
  104. if (prlimit(TT.P, map[i], &rr, 0)) perror_exit(0);
  105. }
  106. }