forked from landley/toybox
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This isn't a shell builtin, it uses prlimit to target any pid (without -P it defaults to $PPID, so acts like historical ulimit by default).
- Loading branch information
Showing
2 changed files
with
126 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* ulimit.c - Modify resource limits | ||
* | ||
* Copyright 2015 Rob Landley <[email protected]> | ||
* | ||
* See http:https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ulimit.html | ||
* And man prlimit(2). | ||
* | ||
* Deviations from posix: The units on -f are supposed to be 512 byte | ||
* "blocks" (no other options are specified, and even hard drives don't | ||
* do that anymore). Bash uses 1024 byte blocks, so they don't care either. | ||
* We consistently use bytes everywhere we can. | ||
* | ||
* Deviations from bash: Sizes are in bytes (instead of -p 512 and -f 1024). | ||
* Bash's -p value has been wrong since 2010 (git 35f3d14dbbc5). | ||
* The kernel implementation of RLIMIT_LOCKS (-x) was removed from Linux in | ||
* 2003. Bash never implemented -b (it's in the help but unrecognized at | ||
* runtime). We support -P to affect processes other than us. | ||
USE_ULIMIT(NEWTOY(ulimit, ">1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]", TOYFLAG_USR|TOYFLAG_BIN)) | ||
config ULIMIT | ||
bool "ulimit" | ||
default y | ||
help | ||
usage: ulimit [-P PID] [-SHRacdefilmnpqrstuv] [LIMIT] | ||
Print or set resource limits for process number PID. If no LIMIT specified | ||
(or read-only -ap selected) display current value (sizes in bytes). | ||
Default is ulimit -P $PPID -Sf" (show soft filesize of your shell). | ||
-S Set/show soft limit -H Set/show hard (maximum) limit | ||
-a Show all limits -c Core file size | ||
-d Process data segment -e Max scheduling priority | ||
-f Output file size -i Pending signal count | ||
-l Locked memory -m Resident Set Size | ||
-n Number of open files -p Pipe buffer | ||
-q Posix message queue -r Max Real-time priority | ||
-R Realtime latency (usec) -s Stack size | ||
-t Total CPU time (in seconds) -u Maximum processes (under this UID) | ||
-v Virtual memory size -P PID to affect (default $PPID) | ||
*/ | ||
|
||
#define FOR_ulimit | ||
#include "toys.h" | ||
|
||
GLOBALS( | ||
long pid; | ||
) | ||
|
||
// This is a linux kernel syscall added in 2.6.36 (git c022a0acad53) which | ||
// glibc only exports a wrapper prototype for if you #define _FSF_HURD_RULZE. | ||
int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, | ||
struct rlimit *old_limit); | ||
|
||
// I'd like to sort the RLIMIT values 0-15, but mips, alpha and sparc | ||
// override the asm-generic values for 5-9. Also, the kernel implementation | ||
// of RLIMIT_LOCKS (-x) was removed from Linux in 2003. | ||
void ulimit_main(void) | ||
{ | ||
struct rlimit rr; | ||
int i; | ||
// Order is cdefilmnqRrstuv | ||
char map[] = {RLIMIT_CORE, RLIMIT_DATA, RLIMIT_NICE, RLIMIT_FSIZE, | ||
RLIMIT_SIGPENDING, RLIMIT_MEMLOCK, RLIMIT_RSS, RLIMIT_NOFILE, 0, | ||
RLIMIT_MSGQUEUE, RLIMIT_RTTIME, RLIMIT_RTPRIO, RLIMIT_STACK, | ||
RLIMIT_CPU, RLIMIT_NPROC, RLIMIT_AS}; | ||
|
||
if (!(toys.optflags&(FLAG_H-1))) toys.optflags |= FLAG_f; | ||
if ((toys.optflags&(FLAG_a|FLAG_p)) && toys.optc) error_exit("can't set -ap"); | ||
|
||
// Fetch data | ||
if (!(toys.optflags&FLAG_P)) TT.pid = getppid(); | ||
|
||
for (i=0; i<sizeof(map); i++) { | ||
char *flags="cdefilmnpqRrstuv"; | ||
|
||
int get = toys.optflags&(FLAG_a|(1<<i)); | ||
|
||
if (get && prlimit(TT.pid, map[i], 0, &rr)) perror_exit("-%c", flags[i]); | ||
if (!toys.optc) { | ||
if (toys.optflags&FLAG_a) printf("-%c: ", flags[i]); | ||
if (get) { | ||
if ((1<<i)&FLAG_p) { | ||
if (toys.optflags&FLAG_H) | ||
xreadfile("/proc/sys/fs/pipe-max-size", toybuf, sizeof(toybuf)); | ||
else { | ||
int pp[2]; | ||
|
||
xpipe(pp); | ||
sprintf(toybuf, "%d\n", fcntl(*pp, F_GETPIPE_SZ)); | ||
} | ||
printf("%s", toybuf); | ||
} else { | ||
rlim_t rl = (toys.optflags&FLAG_H) ? rr.rlim_max : rr.rlim_cur; | ||
|
||
if (rl == RLIM_INFINITY) printf("unlimited\n"); | ||
else printf("%ld\n", (long)rl); | ||
} | ||
} | ||
} | ||
if (toys.optflags&(1<<i)) break; | ||
} | ||
|
||
if (toys.optflags&(FLAG_a|FLAG_p)) return; | ||
|
||
if (toys.optc) { | ||
rlim_t val; | ||
|
||
if (tolower(**toys.optargs == 'i')) val = RLIM_INFINITY; | ||
else val = atolx_range(*toys.optargs, 0, LONG_MAX); | ||
|
||
if (toys.optflags&FLAG_H) rr.rlim_max = val; | ||
else rr.rlim_cur = val; | ||
if (prlimit(TT.pid, map[i], &rr, 0)) perror_exit(0); | ||
} | ||
} |