Add ulimit.
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).
This commit is contained in:
parent
a7a869c2d5
commit
2f3f26ea1e
@ -247,6 +247,16 @@ static inline void endutxent(void) {;}
|
||||
#define O_PATH 010000000
|
||||
#endif
|
||||
|
||||
// Glibc won't give you linux-kernel constants unless you say "no, a BUD lite"
|
||||
// even though linux has nothing to do with the FSF and never has.
|
||||
#ifndef F_SETPIPE_SZ
|
||||
#define F_SETPIPE_SZ 1031
|
||||
#endif
|
||||
|
||||
#ifndef F_GETPIPE_SZ
|
||||
#define F_GETPIPE_SZ 1032
|
||||
#endif
|
||||
|
||||
#if defined(__SIZEOF_DOUBLE__) && defined(__SIZEOF_LONG__) \
|
||||
&& __SIZEOF_DOUBLE__ <= __SIZEOF_LONG__
|
||||
typedef double FLOAT;
|
||||
|
116
toys/posix/ulimit.c
Normal file
116
toys/posix/ulimit.c
Normal file
@ -0,0 +1,116 @@
|
||||
/* ulimit.c - Modify resource limits
|
||||
*
|
||||
* Copyright 2015 Rob Landley <rob@landley.net>
|
||||
*
|
||||
* See http://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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user