The attached patch adds a new shell builtin, "prlimit", which is similar
to ulimit but can operate on any process (not just the current process),
by using Linux's prlimit() function.
prlimit takes a PID as a first argument, and then processes the rest of
its arguments identically to ulimit, e.g.:
prlimit 3431 -c unlimited
Maybe this is of general interest?
--
"Don't be afraid to ask (λf.((λx.xx) (λr.f(rr))))."
diff --git a/shell/Config.src b/shell/Config.src
index b31e62d..8c3b2a5 100644
--- a/shell/Config.src
+++ b/shell/Config.src
@@ -145,5 +145,14 @@ config FEATURE_SH_HISTFILESIZE
to set shell history size. Note that its max value is capped
by "History size" setting in library tuning section.
+config FEATURE_PRLIMIT
+ bool "Enable prlimit builtin command"
+ default n
+ depends on ASH || HUSH
+ select PLATFORM_LINUX
+ help
+ Enable prlimit, which is like ulimit but operates on any PID,
+ not just the current process.
+
endmenu
diff --git a/shell/ash.c b/shell/ash.c
index fbbdb06..7c8b20c 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -9044,6 +9044,9 @@ static int trapcmd(int, char **) FAST_FUNC;
static int umaskcmd(int, char **) FAST_FUNC;
static int unsetcmd(int, char **) FAST_FUNC;
static int ulimitcmd(int, char **) FAST_FUNC;
+#if ENABLE_FEATURE_PRLIMIT
+static int prlimitcmd(int, char **) FAST_FUNC;
+#endif
#define BUILTIN_NOSPEC "0"
#define BUILTIN_SPECIAL "1"
@@ -9117,6 +9120,9 @@ static const struct builtincmd builtintab[] = {
#if ENABLE_ASH_BUILTIN_PRINTF
{ BUILTIN_REGULAR "printf" , printfcmd },
#endif
+#if ENABLE_FEATURE_PRLIMIT
+ { BUILTIN_NOSPEC "prlimit" , prlimitcmd },
+#endif
{ BUILTIN_NOSPEC "pwd" , pwdcmd },
{ BUILTIN_REGULAR "read" , readcmd },
{ BUILTIN_SPEC_REG_ASSG "readonly", exportcmd },
@@ -12918,6 +12924,14 @@ ulimitcmd(int argc UNUSED_PARAM, char **argv)
return shell_builtin_ulimit(argv);
}
+#if ENABLE_FEATURE_PRLIMIT
+static int FAST_FUNC
+prlimitcmd(int argc UNUSED_PARAM, char **argv)
+{
+ return shell_builtin_ulimit(argv);
+}
+#endif
+
/* ============ main() and helpers */
/*
diff --git a/shell/hush.c b/shell/hush.c
index e2dc1e2..74721ad 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -940,6 +940,9 @@ static const struct built_in_command bltins1[] = {
BLTIN("trap" , builtin_trap , "Trap signals"),
BLTIN("type" , builtin_type , "Show command type"),
BLTIN("ulimit" , shell_builtin_ulimit , "Control resource limits"),
+#if ENABLE_FEATURE_PRLIMIT
+ BLTIN("prlimit" , shell_builtin_ulimit , "Control resource limits on other processes"),
+#endif
BLTIN("umask" , builtin_umask , "Set file creation mask"),
BLTIN("unset" , builtin_unset , "Unset variables"),
BLTIN("wait" , builtin_wait , "Wait for process"),
diff --git a/shell/shell_common.c b/shell/shell_common.c
index 0051f21..26a0392 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -390,6 +390,10 @@ static void printlim(unsigned opts, const struct rlimit *limit,
int FAST_FUNC
shell_builtin_ulimit(char **argv)
{
+#if ENABLE_FEATURE_PRLIMIT
+ pid_t pid = 0;
+#endif
+
unsigned opts;
unsigned argc;
@@ -408,6 +412,24 @@ shell_builtin_ulimit(char **argv)
#endif
/* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */
+#if ENABLE_FEATURE_PRLIMIT
+ if (strcmp(argv[0], "prlimit") == 0) {
+ if (!argv[1]) {
+ bb_error_msg("no PID given");
+ return EXIT_FAILURE;
+ }
+
+ /* Mostly copied from procps/kill.c:kill_main(): */
+ pid = bb_strtoi(argv[1], NULL, 10);
+ if (errno && (errno != EINVAL)) {
+ bb_error_msg("invalid PID '%s'", argv[1]);
+ return EXIT_FAILURE;
+ }
+ argv++;
+ *argv = "ulimit";
+ }
+#endif
+
argc = 1;
while (argv[argc])
argc++;
@@ -431,7 +453,11 @@ shell_builtin_ulimit(char **argv)
if (opt_char == 'a') {
for (l = limits_tbl; l != &limits_tbl[ARRAY_SIZE(limits_tbl)]; l++) {
+#if ENABLE_FEATURE_PRLIMIT
+ prlimit(pid, l->cmd, NULL, &limit);
+#else
getrlimit(l->cmd, &limit);
+#endif
printf("-%c: %-30s ", l->option, l->name);
printlim(opts, &limit, l);
}
@@ -444,7 +470,11 @@ shell_builtin_ulimit(char **argv)
if (opt_char == l->option) {
char *val_str;
+#if ENABLE_FEATURE_PRLIMIT
+ prlimit(pid, l->cmd, NULL, &limit);
+#else
getrlimit(l->cmd, &limit);
+#endif
val_str = optarg;
if (!val_str && argv[optind] && argv[optind][0] != '-')
@@ -478,7 +508,12 @@ shell_builtin_ulimit(char **argv)
if (opts & OPT_soft)
limit.rlim_cur = val;
//bb_error_msg("setrlimit(%d, %lld, %lld)", l->cmd, (long long)limit.rlim_cur, (long long)limit.rlim_max);
- if (setrlimit(l->cmd, &limit) < 0) {
+#if ENABLE_FEATURE_PRLIMIT
+ if (prlimit(pid, l->cmd, &limit, NULL) < 0)
+#else
+ if (setrlimit(l->cmd, &limit) < 0)
+#endif
+ {
bb_perror_msg("error setting limit");
return EXIT_FAILURE;
}
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox