Moved from the ulimit builtin from shell/ash.c and slightly adapted.

Signed-off-by: Tobias Klauser <[email protected]>
---
 shell/Kbuild           |    4 +-
 shell/ash.c            |  214 +-----------------------------------------------
 shell/builtin_ulimit.c |  202 +++++++++++++++++++++++++++++++++++++++++++++
 shell/builtin_ulimit.h |   19 ++++
 shell/hush.c           |    4 +-
 5 files changed, 228 insertions(+), 215 deletions(-)
 create mode 100644 shell/builtin_ulimit.c
 create mode 100644 shell/builtin_ulimit.h

diff --git a/shell/Kbuild b/shell/Kbuild
index d8306dc..8b52865 100644
--- a/shell/Kbuild
+++ b/shell/Kbuild
@@ -5,8 +5,8 @@
 # Licensed under the GPL v2, see the file LICENSE in this tarball.
 
 lib-y:=
-lib-$(CONFIG_ASH)      += ash.o ash_ptr_hack.o shell_common.o builtin_read.o
-lib-$(CONFIG_HUSH)     += hush.o match.o shell_common.o builtin_read.o
+lib-$(CONFIG_ASH)      += ash.o ash_ptr_hack.o shell_common.o builtin_read.o 
builtin_ulimit.o
+lib-$(CONFIG_HUSH)     += hush.o match.o shell_common.o builtin_read.o 
builtin_ulimit.o
 lib-$(CONFIG_CTTYHACK) += cttyhack.o
 
 lib-$(CONFIG_SH_MATH_SUPPORT) += math.o
diff --git a/shell/ash.c b/shell/ash.c
index 03904bb..e938fa5 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -51,6 +51,7 @@
 
 #include "shell_common.h"
 #include "builtin_read.h"
+#include "builtin_ulimit.h"
 #include "math.h"
 #if ENABLE_ASH_RANDOM_SUPPORT
 # include "random.h"
@@ -12614,219 +12615,10 @@ umaskcmd(int argc UNUSED_PARAM, char **argv)
        return 0;
 }
 
-/*
- * ulimit builtin
- *
- * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
- * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
- * ash by J.T. Conklin.
- *
- * Public domain.
- */
-struct limits {
-       uint8_t cmd;          /* RLIMIT_xxx fit into it */
-       uint8_t factor_shift; /* shift by to get rlim_{cur,max} values */
-       char    option;
-};
-
-static const struct limits limits_tbl[] = {
-#ifdef RLIMIT_CPU
-       { RLIMIT_CPU,        0, 't' },
-#endif
-#ifdef RLIMIT_FSIZE
-       { RLIMIT_FSIZE,      9, 'f' },
-#endif
-#ifdef RLIMIT_DATA
-       { RLIMIT_DATA,      10, 'd' },
-#endif
-#ifdef RLIMIT_STACK
-       { RLIMIT_STACK,     10, 's' },
-#endif
-#ifdef RLIMIT_CORE
-       { RLIMIT_CORE,       9, 'c' },
-#endif
-#ifdef RLIMIT_RSS
-       { RLIMIT_RSS,       10, 'm' },
-#endif
-#ifdef RLIMIT_MEMLOCK
-       { RLIMIT_MEMLOCK,   10, 'l' },
-#endif
-#ifdef RLIMIT_NPROC
-       { RLIMIT_NPROC,      0, 'p' },
-#endif
-#ifdef RLIMIT_NOFILE
-       { RLIMIT_NOFILE,     0, 'n' },
-#endif
-#ifdef RLIMIT_AS
-       { RLIMIT_AS,        10, 'v' },
-#endif
-#ifdef RLIMIT_LOCKS
-       { RLIMIT_LOCKS,      0, 'w' },
-#endif
-};
-static const char limits_name[] =
-#ifdef RLIMIT_CPU
-       "time(seconds)" "\0"
-#endif
-#ifdef RLIMIT_FSIZE
-       "file(blocks)" "\0"
-#endif
-#ifdef RLIMIT_DATA
-       "data(kb)" "\0"
-#endif
-#ifdef RLIMIT_STACK
-       "stack(kb)" "\0"
-#endif
-#ifdef RLIMIT_CORE
-       "coredump(blocks)" "\0"
-#endif
-#ifdef RLIMIT_RSS
-       "memory(kb)" "\0"
-#endif
-#ifdef RLIMIT_MEMLOCK
-       "locked memory(kb)" "\0"
-#endif
-#ifdef RLIMIT_NPROC
-       "process" "\0"
-#endif
-#ifdef RLIMIT_NOFILE
-       "nofiles" "\0"
-#endif
-#ifdef RLIMIT_AS
-       "vmemory(kb)" "\0"
-#endif
-#ifdef RLIMIT_LOCKS
-       "locks" "\0"
-#endif
-;
-
-enum limtype { SOFT = 0x1, HARD = 0x2 };
-
-static void
-printlim(enum limtype how, const struct rlimit *limit,
-                       const struct limits *l)
-{
-       rlim_t val;
-
-       val = limit->rlim_max;
-       if (how & SOFT)
-               val = limit->rlim_cur;
-
-       if (val == RLIM_INFINITY)
-               out1fmt("unlimited\n");
-       else {
-               val >>= l->factor_shift;
-               out1fmt("%lld\n", (long long) val);
-       }
-}
-
 static int FAST_FUNC
-ulimitcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
+ulimitcmd(int argc UNUSED_PARAM, char **argv)
 {
-       rlim_t val;
-       enum limtype how = SOFT | HARD;
-       const struct limits *l;
-       int set, all = 0;
-       int optc, what;
-       struct rlimit limit;
-
-       what = 'f';
-       while ((optc = nextopt("HSa"
-#ifdef RLIMIT_CPU
-                               "t"
-#endif
-#ifdef RLIMIT_FSIZE
-                               "f"
-#endif
-#ifdef RLIMIT_DATA
-                               "d"
-#endif
-#ifdef RLIMIT_STACK
-                               "s"
-#endif
-#ifdef RLIMIT_CORE
-                               "c"
-#endif
-#ifdef RLIMIT_RSS
-                               "m"
-#endif
-#ifdef RLIMIT_MEMLOCK
-                               "l"
-#endif
-#ifdef RLIMIT_NPROC
-                               "p"
-#endif
-#ifdef RLIMIT_NOFILE
-                               "n"
-#endif
-#ifdef RLIMIT_AS
-                               "v"
-#endif
-#ifdef RLIMIT_LOCKS
-                               "w"
-#endif
-                                       )) != '\0')
-               switch (optc) {
-               case 'H':
-                       how = HARD;
-                       break;
-               case 'S':
-                       how = SOFT;
-                       break;
-               case 'a':
-                       all = 1;
-                       break;
-               default:
-                       what = optc;
-               }
-
-       for (l = limits_tbl; l->option != what; l++)
-               continue;
-
-       set = *argptr ? 1 : 0;
-       val = 0;
-       if (set) {
-               char *p = *argptr;
-
-               if (all || argptr[1])
-                       ash_msg_and_raise_error("too many arguments");
-               if (strncmp(p, "unlimited\n", 9) == 0)
-                       val = RLIM_INFINITY;
-               else {
-                       if (sizeof(val) == sizeof(int))
-                               val = bb_strtou(p, NULL, 10);
-                       else if (sizeof(val) == sizeof(long))
-                               val = bb_strtoul(p, NULL, 10);
-                       else
-                               val = bb_strtoull(p, NULL, 10);
-                       if (errno)
-                               ash_msg_and_raise_error("bad number");
-                       val <<= l->factor_shift;
-               }
-       }
-       if (all) {
-               const char *lname = limits_name;
-               for (l = limits_tbl; l != &limits_tbl[ARRAY_SIZE(limits_tbl)]; 
l++) {
-                       getrlimit(l->cmd, &limit);
-                       out1fmt("%-20s ", lname);
-                       lname += strlen(lname) + 1;
-                       printlim(how, &limit, l);
-               }
-               return 0;
-       }
-
-       getrlimit(l->cmd, &limit);
-       if (set) {
-               if (how & HARD)
-                       limit.rlim_max = val;
-               if (how & SOFT)
-                       limit.rlim_cur = val;
-               if (setrlimit(l->cmd, &limit) < 0)
-                       ash_msg_and_raise_error("error setting limit (%m)");
-       } else {
-               printlim(how, &limit, l);
-       }
-       return 0;
+       return shell_builtin_ulimit(argv);
 }
 
 /* ============ main() and helpers */
diff --git a/shell/builtin_ulimit.c b/shell/builtin_ulimit.c
new file mode 100644
index 0000000..2ed7b49
--- /dev/null
+++ b/shell/builtin_ulimit.c
@@ -0,0 +1,202 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * ulimit builtin
+ *
+ * Adapted from ash applet code
+ *
+ * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
+ * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
+ * ash by J.T. Conklin.
+ *
+ * Public domain.
+
+ * Copyright (c) 2010 Tobias Klauser
+ * Split from ash.c and slightly adapted.
+ *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+ */
+#include "libbb.h"
+#include "builtin_ulimit.h"
+
+#include <string.h>
+#include <errno.h>
+
+struct limits {
+       uint8_t cmd;                    /* RLIMIT_xxx fit into it */
+       uint8_t factor_shift;   /* shift by to get rlim_{cur,max} values */
+       char option;
+       const char *name;
+};
+
+static const struct limits limits_tbl[] = {
+#ifdef RLIMIT_CPU
+       { RLIMIT_CPU,           0,      't',    "cpu time (seconds)" },
+#endif
+#ifdef RLIMIT_FSIZE
+       { RLIMIT_FSIZE,         9,      'f',    "file size (blocks)" },
+#endif
+#ifdef RLIMIT_DATA
+       { RLIMIT_DATA,          10,     'd',    "data seg size (kb)" },
+#endif
+#ifdef RLIMIT_STACK
+       { RLIMIT_STACK,         10,     's',    "stack size (kb)" },
+#endif
+#ifdef RLIMIT_CORE
+       { RLIMIT_CORE,          9,      'c',    "core file size (blocks)" },
+#endif
+#ifdef RLIMIT_RSS
+       { RLIMIT_RSS,           10,     'm',    "resident set size (kb)" },
+#endif
+#ifdef RLIMIT_MEMLOCK
+       { RLIMIT_MEMLOCK,       10,     'l',    "locked memory (kb)" },
+#endif
+#ifdef RLIMIT_NPROC
+       { RLIMIT_NPROC,         0,      'p',    "processes" },
+#endif
+#ifdef RLIMIT_NOFILE
+       { RLIMIT_NOFILE,        0,      'n',    "file descriptors" },
+#endif
+#ifdef RLIMIT_AS
+       { RLIMIT_AS,            10,     'v',    "address space (kb)" },
+#endif
+#ifdef RLIMIT_LOCKS
+       { RLIMIT_LOCKS,         0,      'w',    "locks" },
+#endif
+};
+
+enum limtype { SOFT = 0x1, HARD = 0x2 };
+
+static void printlim(enum limtype how, const struct rlimit *limit,
+                       const struct limits *l)
+{
+       rlim_t val;
+
+       val = limit->rlim_max;
+       if (how & SOFT)
+               val = limit->rlim_cur;
+
+       if (val == RLIM_INFINITY)
+               printf("unlimited\n");
+       else {
+               val >>= l->factor_shift;
+               printf("%lld\n", (long long) val);
+       }
+}
+
+static const char ulimit_opt_string[] = "!HSa"
+#ifdef RLIMIT_CPU
+                       "t"
+#endif
+#ifdef RLIMIT_FSIZE
+                       "f"
+#endif
+#ifdef RLIMIT_DATA
+                       "d"
+#endif
+#ifdef RLIMIT_STACK
+                       "s"
+#endif
+#ifdef RLIMIT_CORE
+                       "c"
+#endif
+#ifdef RLIMIT_RSS
+                       "m"
+#endif
+#ifdef RLIMIT_MEMLOCK
+                       "l"
+#endif
+#ifdef RLIMIT_NPROC
+                       "p"
+#endif
+#ifdef RLIMIT_NOFILE
+                       "n"
+#endif
+#ifdef RLIMIT_AS
+                       "v"
+#endif
+#ifdef RLIMIT_LOCKS
+                       "w"
+#endif
+                       ;
+
+int FAST_FUNC shell_builtin_ulimit(char **argv)
+{
+       uint32_t flags;
+       int set, all = 0;
+       int how = SOFT | HARD;
+       const struct limits *l;
+       rlim_t val;
+       struct rlimit limit;
+
+       l = &limits_tbl[1];     /* default to '-f' */
+       flags = getopt32(argv, ulimit_opt_string);
+       if (flags == (uint32_t)-1)
+               return EXIT_FAILURE;
+       if (flags & 1)
+               how = HARD;
+       if (flags & 2)
+               how = SOFT;
+       if (flags & 4)
+               all = 1;
+
+       if (all && (flags & ~0x7)) {
+               bb_error_msg("ulimit: no limits allowed with -a");
+               return EXIT_FAILURE;
+       }
+
+       flags >>= 3;
+       l = limits_tbl;
+       for ( ; flags; flags >>= 1, l++) {
+               /* Only consider the first matching option */
+               if (flags & 1)
+                       break;
+       }
+
+       argv += optind;
+       set = *argv ? 1 : 0;
+       val = 0;
+       if (set) {
+               char *p = *argv;
+
+               if (strncmp(p, "unlimited", 9) == 0)
+                       val = RLIM_INFINITY;
+               else {
+                       if (sizeof(val) == sizeof(int))
+                               val = bb_strtou(p, NULL, 10);
+                       else if (sizeof(val) == sizeof(long))
+                               val = bb_strtoul(p, NULL, 10);
+                       else
+                               val = bb_strtoull(p, NULL, 10);
+                       if (errno) {
+                               bb_error_msg("ulimit: bad number");
+                               return EXIT_FAILURE;
+                       }
+                       val <<= l->factor_shift;
+               }
+       }
+
+       if (all) {
+               for (l = limits_tbl; l != &limits_tbl[ARRAY_SIZE(limits_tbl)]; 
l++) {
+                       getrlimit(l->cmd, &limit);
+                       printf("-%c: %-30s ", l->option, l->name);
+                       printlim(how, &limit, l);
+               }
+               return 0;
+       }
+
+       getrlimit(l->cmd, &limit);
+       if (set) {
+               if (how & HARD)
+                       limit.rlim_max = val;
+               if (how & SOFT)
+                       limit.rlim_cur = val;
+               if (setrlimit(l->cmd, &limit) < 0) {
+                       bb_error_msg("ulimit: error setting limit: %s", 
strerror(errno));
+                       return EXIT_FAILURE;
+               }
+       } else {
+               printlim(how, &limit, l);
+       }
+
+       return 0;
+}
diff --git a/shell/builtin_ulimit.h b/shell/builtin_ulimit.h
new file mode 100644
index 0000000..ec1af78
--- /dev/null
+++ b/shell/builtin_ulimit.h
@@ -0,0 +1,19 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Adapted from ash applet code
+ *
+ * Copyright (c) 2010 Tobias Klauser
+ * Split from ash.c and slightly adapted.
+ *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
+ */
+#ifndef SHELL_BUILTIN_ULIMIT_H
+#define SHELL_BUILTIN_ULIMIT_H 1
+
+PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
+
+int FAST_FUNC shell_builtin_ulimit(char **argv);
+
+POP_SAVED_FUNCTION_VISIBILITY
+
+#endif
diff --git a/shell/hush.c b/shell/hush.c
index 0310b02..6f391b8 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -57,7 +57,6 @@
  *
  * TODOs:
  *      grep for "TODO" and fix (some of them are easy)
- *      builtins: ulimit
  *      special variables (done: PWD)
  *      follow IFS rules more precisely, including update semantics
  *      export builtin should be special, its arguments are assignments
@@ -87,6 +86,7 @@
 
 #include "shell_common.h"
 #include "builtin_read.h"
+#include "builtin_ulimit.h"
 #include "math.h"
 #include "match.h"
 #if ENABLE_HUSH_RANDOM_SUPPORT
@@ -671,7 +671,7 @@ static const struct built_in_command bltins1[] = {
        BLTIN("shift"    , builtin_shift   , "Shift positional parameters"),
        BLTIN("trap"     , builtin_trap    , "Trap signals"),
        BLTIN("type"     , builtin_type    , "Write a description of command 
type"),
-//     BLTIN("ulimit"   , builtin_ulimit  , "Control resource limits"),
+       BLTIN("ulimit"   , shell_builtin_ulimit  , "Control resource limits"),
        BLTIN("umask"    , builtin_umask   , "Set file creation mask"),
        BLTIN("unset"    , builtin_unset   , "Unset variables"),
        BLTIN("wait"     , builtin_wait    , "Wait for process"),
-- 
1.6.3.3

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to