diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-06 20:12:00 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-03-06 20:12:00 +0100 |
| commit | f3c742f925c31bdf1b0d52c82e0ef608a344e10f (patch) | |
| tree | c74cf752e03ef906fc74014882843640262a2322 /shell | |
| parent | cbcc1236f806f18e6386e6e1f495a9832b7d307d (diff) | |
| download | busybox-w32-f3c742f925c31bdf1b0d52c82e0ef608a344e10f.tar.gz busybox-w32-f3c742f925c31bdf1b0d52c82e0ef608a344e10f.tar.bz2 busybox-w32-f3c742f925c31bdf1b0d52c82e0ef608a344e10f.zip | |
hush: use ash's ulimit builtin; make it more more bash0like while at it
Based on a patch by Tobias Klauser <tklauser@distanz.ch>
function old new delta
shell_builtin_ulimit - 498 +498
limits_tbl 33 88 +55
ulimit_opt_string - 38 +38
bltins1 288 300 +12
limits_name 127 - -127
ulimitcmd 415 7 -408
------------------------------------------------------------------------------
(add/remove: 3/1 grow/shrink: 2/1 up/down: 603/-535) Total: 68 bytes
text data bss dec hex filename
839229 453 6828 846510 ceaae busybox_old
839423 453 6828 846704 ceb70 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/Kbuild | 4 | ||||
| -rw-r--r-- | shell/ash.c | 214 | ||||
| -rw-r--r-- | shell/builtin_ulimit.c | 227 | ||||
| -rw-r--r-- | shell/builtin_ulimit.h | 19 | ||||
| -rw-r--r-- | shell/hush.c | 4 |
5 files changed, 253 insertions, 215 deletions
diff --git a/shell/Kbuild b/shell/Kbuild index d8306dc96..8b528654a 100644 --- a/shell/Kbuild +++ b/shell/Kbuild | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | # Licensed under the GPL v2, see the file LICENSE in this tarball. | 5 | # Licensed under the GPL v2, see the file LICENSE in this tarball. |
| 6 | 6 | ||
| 7 | lib-y:= | 7 | lib-y:= |
| 8 | lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o builtin_read.o | 8 | lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o builtin_read.o builtin_ulimit.o |
| 9 | lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o builtin_read.o | 9 | lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o builtin_read.o builtin_ulimit.o |
| 10 | lib-$(CONFIG_CTTYHACK) += cttyhack.o | 10 | lib-$(CONFIG_CTTYHACK) += cttyhack.o |
| 11 | 11 | ||
| 12 | lib-$(CONFIG_SH_MATH_SUPPORT) += math.o | 12 | lib-$(CONFIG_SH_MATH_SUPPORT) += math.o |
diff --git a/shell/ash.c b/shell/ash.c index 8ffe67cca..0a8b6c0f2 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -51,6 +51,7 @@ | |||
| 51 | 51 | ||
| 52 | #include "shell_common.h" | 52 | #include "shell_common.h" |
| 53 | #include "builtin_read.h" | 53 | #include "builtin_read.h" |
| 54 | #include "builtin_ulimit.h" | ||
| 54 | #include "math.h" | 55 | #include "math.h" |
| 55 | #if ENABLE_ASH_RANDOM_SUPPORT | 56 | #if ENABLE_ASH_RANDOM_SUPPORT |
| 56 | # include "random.h" | 57 | # include "random.h" |
| @@ -12614,219 +12615,10 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) | |||
| 12614 | return 0; | 12615 | return 0; |
| 12615 | } | 12616 | } |
| 12616 | 12617 | ||
| 12617 | /* | ||
| 12618 | * ulimit builtin | ||
| 12619 | * | ||
| 12620 | * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and | ||
| 12621 | * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with | ||
| 12622 | * ash by J.T. Conklin. | ||
| 12623 | * | ||
| 12624 | * Public domain. | ||
| 12625 | */ | ||
| 12626 | struct limits { | ||
| 12627 | uint8_t cmd; /* RLIMIT_xxx fit into it */ | ||
| 12628 | uint8_t factor_shift; /* shift by to get rlim_{cur,max} values */ | ||
| 12629 | char option; | ||
| 12630 | }; | ||
| 12631 | |||
| 12632 | static const struct limits limits_tbl[] = { | ||
| 12633 | #ifdef RLIMIT_CPU | ||
| 12634 | { RLIMIT_CPU, 0, 't' }, | ||
| 12635 | #endif | ||
| 12636 | #ifdef RLIMIT_FSIZE | ||
| 12637 | { RLIMIT_FSIZE, 9, 'f' }, | ||
| 12638 | #endif | ||
| 12639 | #ifdef RLIMIT_DATA | ||
| 12640 | { RLIMIT_DATA, 10, 'd' }, | ||
| 12641 | #endif | ||
| 12642 | #ifdef RLIMIT_STACK | ||
| 12643 | { RLIMIT_STACK, 10, 's' }, | ||
| 12644 | #endif | ||
| 12645 | #ifdef RLIMIT_CORE | ||
| 12646 | { RLIMIT_CORE, 9, 'c' }, | ||
| 12647 | #endif | ||
| 12648 | #ifdef RLIMIT_RSS | ||
| 12649 | { RLIMIT_RSS, 10, 'm' }, | ||
| 12650 | #endif | ||
| 12651 | #ifdef RLIMIT_MEMLOCK | ||
| 12652 | { RLIMIT_MEMLOCK, 10, 'l' }, | ||
| 12653 | #endif | ||
| 12654 | #ifdef RLIMIT_NPROC | ||
| 12655 | { RLIMIT_NPROC, 0, 'p' }, | ||
| 12656 | #endif | ||
| 12657 | #ifdef RLIMIT_NOFILE | ||
| 12658 | { RLIMIT_NOFILE, 0, 'n' }, | ||
| 12659 | #endif | ||
| 12660 | #ifdef RLIMIT_AS | ||
| 12661 | { RLIMIT_AS, 10, 'v' }, | ||
| 12662 | #endif | ||
| 12663 | #ifdef RLIMIT_LOCKS | ||
| 12664 | { RLIMIT_LOCKS, 0, 'w' }, | ||
| 12665 | #endif | ||
| 12666 | }; | ||
| 12667 | static const char limits_name[] = | ||
| 12668 | #ifdef RLIMIT_CPU | ||
| 12669 | "time(seconds)" "\0" | ||
| 12670 | #endif | ||
| 12671 | #ifdef RLIMIT_FSIZE | ||
| 12672 | "file(blocks)" "\0" | ||
| 12673 | #endif | ||
| 12674 | #ifdef RLIMIT_DATA | ||
| 12675 | "data(kb)" "\0" | ||
| 12676 | #endif | ||
| 12677 | #ifdef RLIMIT_STACK | ||
| 12678 | "stack(kb)" "\0" | ||
| 12679 | #endif | ||
| 12680 | #ifdef RLIMIT_CORE | ||
| 12681 | "coredump(blocks)" "\0" | ||
| 12682 | #endif | ||
| 12683 | #ifdef RLIMIT_RSS | ||
| 12684 | "memory(kb)" "\0" | ||
| 12685 | #endif | ||
| 12686 | #ifdef RLIMIT_MEMLOCK | ||
| 12687 | "locked memory(kb)" "\0" | ||
| 12688 | #endif | ||
| 12689 | #ifdef RLIMIT_NPROC | ||
| 12690 | "process" "\0" | ||
| 12691 | #endif | ||
| 12692 | #ifdef RLIMIT_NOFILE | ||
| 12693 | "nofiles" "\0" | ||
| 12694 | #endif | ||
| 12695 | #ifdef RLIMIT_AS | ||
| 12696 | "vmemory(kb)" "\0" | ||
| 12697 | #endif | ||
| 12698 | #ifdef RLIMIT_LOCKS | ||
| 12699 | "locks" "\0" | ||
| 12700 | #endif | ||
| 12701 | ; | ||
| 12702 | |||
| 12703 | enum limtype { SOFT = 0x1, HARD = 0x2 }; | ||
| 12704 | |||
| 12705 | static void | ||
| 12706 | printlim(enum limtype how, const struct rlimit *limit, | ||
| 12707 | const struct limits *l) | ||
| 12708 | { | ||
| 12709 | rlim_t val; | ||
| 12710 | |||
| 12711 | val = limit->rlim_max; | ||
| 12712 | if (how & SOFT) | ||
| 12713 | val = limit->rlim_cur; | ||
| 12714 | |||
| 12715 | if (val == RLIM_INFINITY) | ||
| 12716 | out1fmt("unlimited\n"); | ||
| 12717 | else { | ||
| 12718 | val >>= l->factor_shift; | ||
| 12719 | out1fmt("%lld\n", (long long) val); | ||
| 12720 | } | ||
| 12721 | } | ||
| 12722 | |||
| 12723 | static int FAST_FUNC | 12618 | static int FAST_FUNC |
| 12724 | ulimitcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | 12619 | ulimitcmd(int argc UNUSED_PARAM, char **argv) |
| 12725 | { | 12620 | { |
| 12726 | rlim_t val; | 12621 | return shell_builtin_ulimit(argv); |
| 12727 | enum limtype how = SOFT | HARD; | ||
| 12728 | const struct limits *l; | ||
| 12729 | int set, all = 0; | ||
| 12730 | int optc, what; | ||
| 12731 | struct rlimit limit; | ||
| 12732 | |||
| 12733 | what = 'f'; | ||
| 12734 | while ((optc = nextopt("HSa" | ||
| 12735 | #ifdef RLIMIT_CPU | ||
| 12736 | "t" | ||
| 12737 | #endif | ||
| 12738 | #ifdef RLIMIT_FSIZE | ||
| 12739 | "f" | ||
| 12740 | #endif | ||
| 12741 | #ifdef RLIMIT_DATA | ||
| 12742 | "d" | ||
| 12743 | #endif | ||
| 12744 | #ifdef RLIMIT_STACK | ||
| 12745 | "s" | ||
| 12746 | #endif | ||
| 12747 | #ifdef RLIMIT_CORE | ||
| 12748 | "c" | ||
| 12749 | #endif | ||
| 12750 | #ifdef RLIMIT_RSS | ||
| 12751 | "m" | ||
| 12752 | #endif | ||
| 12753 | #ifdef RLIMIT_MEMLOCK | ||
| 12754 | "l" | ||
| 12755 | #endif | ||
| 12756 | #ifdef RLIMIT_NPROC | ||
| 12757 | "p" | ||
| 12758 | #endif | ||
| 12759 | #ifdef RLIMIT_NOFILE | ||
| 12760 | "n" | ||
| 12761 | #endif | ||
| 12762 | #ifdef RLIMIT_AS | ||
| 12763 | "v" | ||
| 12764 | #endif | ||
| 12765 | #ifdef RLIMIT_LOCKS | ||
| 12766 | "w" | ||
| 12767 | #endif | ||
| 12768 | )) != '\0') | ||
| 12769 | switch (optc) { | ||
| 12770 | case 'H': | ||
| 12771 | how = HARD; | ||
| 12772 | break; | ||
| 12773 | case 'S': | ||
| 12774 | how = SOFT; | ||
| 12775 | break; | ||
| 12776 | case 'a': | ||
| 12777 | all = 1; | ||
| 12778 | break; | ||
| 12779 | default: | ||
| 12780 | what = optc; | ||
| 12781 | } | ||
| 12782 | |||
| 12783 | for (l = limits_tbl; l->option != what; l++) | ||
| 12784 | continue; | ||
| 12785 | |||
| 12786 | set = *argptr ? 1 : 0; | ||
| 12787 | val = 0; | ||
| 12788 | if (set) { | ||
| 12789 | char *p = *argptr; | ||
| 12790 | |||
| 12791 | if (all || argptr[1]) | ||
| 12792 | ash_msg_and_raise_error("too many arguments"); | ||
| 12793 | if (strncmp(p, "unlimited\n", 9) == 0) | ||
| 12794 | val = RLIM_INFINITY; | ||
| 12795 | else { | ||
| 12796 | if (sizeof(val) == sizeof(int)) | ||
| 12797 | val = bb_strtou(p, NULL, 10); | ||
| 12798 | else if (sizeof(val) == sizeof(long)) | ||
| 12799 | val = bb_strtoul(p, NULL, 10); | ||
| 12800 | else | ||
| 12801 | val = bb_strtoull(p, NULL, 10); | ||
| 12802 | if (errno) | ||
| 12803 | ash_msg_and_raise_error("bad number"); | ||
| 12804 | val <<= l->factor_shift; | ||
| 12805 | } | ||
| 12806 | } | ||
| 12807 | if (all) { | ||
| 12808 | const char *lname = limits_name; | ||
| 12809 | for (l = limits_tbl; l != &limits_tbl[ARRAY_SIZE(limits_tbl)]; l++) { | ||
| 12810 | getrlimit(l->cmd, &limit); | ||
| 12811 | out1fmt("%-20s ", lname); | ||
| 12812 | lname += strlen(lname) + 1; | ||
| 12813 | printlim(how, &limit, l); | ||
| 12814 | } | ||
| 12815 | return 0; | ||
| 12816 | } | ||
| 12817 | |||
| 12818 | getrlimit(l->cmd, &limit); | ||
| 12819 | if (set) { | ||
| 12820 | if (how & HARD) | ||
| 12821 | limit.rlim_max = val; | ||
| 12822 | if (how & SOFT) | ||
| 12823 | limit.rlim_cur = val; | ||
| 12824 | if (setrlimit(l->cmd, &limit) < 0) | ||
| 12825 | ash_msg_and_raise_error("error setting limit (%m)"); | ||
| 12826 | } else { | ||
| 12827 | printlim(how, &limit, l); | ||
| 12828 | } | ||
| 12829 | return 0; | ||
| 12830 | } | 12622 | } |
| 12831 | 12623 | ||
| 12832 | /* ============ main() and helpers */ | 12624 | /* ============ main() and helpers */ |
diff --git a/shell/builtin_ulimit.c b/shell/builtin_ulimit.c new file mode 100644 index 000000000..7e8678341 --- /dev/null +++ b/shell/builtin_ulimit.c | |||
| @@ -0,0 +1,227 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * ulimit builtin | ||
| 4 | * | ||
| 5 | * Adapted from ash applet code | ||
| 6 | * | ||
| 7 | * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and | ||
| 8 | * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with | ||
| 9 | * ash by J.T. Conklin. | ||
| 10 | * | ||
| 11 | * Public domain. | ||
| 12 | * | ||
| 13 | * Copyright (c) 2010 Tobias Klauser | ||
| 14 | * Split from ash.c and slightly adapted. | ||
| 15 | * | ||
| 16 | * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. | ||
| 17 | */ | ||
| 18 | #include "libbb.h" | ||
| 19 | #include "builtin_ulimit.h" | ||
| 20 | |||
| 21 | |||
| 22 | struct limits { | ||
| 23 | uint8_t cmd; /* RLIMIT_xxx fit into it */ | ||
| 24 | uint8_t factor_shift; /* shift by to get rlim_{cur,max} values */ | ||
| 25 | char option; | ||
| 26 | const char *name; | ||
| 27 | }; | ||
| 28 | |||
| 29 | static const struct limits limits_tbl[] = { | ||
| 30 | #ifdef RLIMIT_FSIZE | ||
| 31 | { RLIMIT_FSIZE, 9, 'f', "file size (blocks)" }, | ||
| 32 | #endif | ||
| 33 | #ifdef RLIMIT_CPU | ||
| 34 | { RLIMIT_CPU, 0, 't', "cpu time (seconds)" }, | ||
| 35 | #endif | ||
| 36 | #ifdef RLIMIT_DATA | ||
| 37 | { RLIMIT_DATA, 10, 'd', "data seg size (kb)" }, | ||
| 38 | #endif | ||
| 39 | #ifdef RLIMIT_STACK | ||
| 40 | { RLIMIT_STACK, 10, 's', "stack size (kb)" }, | ||
| 41 | #endif | ||
| 42 | #ifdef RLIMIT_CORE | ||
| 43 | { RLIMIT_CORE, 9, 'c', "core file size (blocks)" }, | ||
| 44 | #endif | ||
| 45 | #ifdef RLIMIT_RSS | ||
| 46 | { RLIMIT_RSS, 10, 'm', "resident set size (kb)" }, | ||
| 47 | #endif | ||
| 48 | #ifdef RLIMIT_MEMLOCK | ||
| 49 | { RLIMIT_MEMLOCK, 10, 'l', "locked memory (kb)" }, | ||
| 50 | #endif | ||
| 51 | #ifdef RLIMIT_NPROC | ||
| 52 | { RLIMIT_NPROC, 0, 'p', "processes" }, | ||
| 53 | #endif | ||
| 54 | #ifdef RLIMIT_NOFILE | ||
| 55 | { RLIMIT_NOFILE, 0, 'n', "file descriptors" }, | ||
| 56 | #endif | ||
| 57 | #ifdef RLIMIT_AS | ||
| 58 | { RLIMIT_AS, 10, 'v', "address space (kb)" }, | ||
| 59 | #endif | ||
| 60 | #ifdef RLIMIT_LOCKS | ||
| 61 | { RLIMIT_LOCKS, 0, 'w', "locks" }, | ||
| 62 | #endif | ||
| 63 | }; | ||
| 64 | |||
| 65 | enum { | ||
| 66 | OPT_hard = (1 << 0), | ||
| 67 | OPT_soft = (1 << 1), | ||
| 68 | }; | ||
| 69 | |||
| 70 | /* "-": treat args as parameters of option with ASCII code 1 */ | ||
| 71 | static const char ulimit_opt_string[] = "-HSa" | ||
| 72 | #ifdef RLIMIT_FSIZE | ||
| 73 | "f::" | ||
| 74 | #endif | ||
| 75 | #ifdef RLIMIT_CPU | ||
| 76 | "t::" | ||
| 77 | #endif | ||
| 78 | #ifdef RLIMIT_DATA | ||
| 79 | "d::" | ||
| 80 | #endif | ||
| 81 | #ifdef RLIMIT_STACK | ||
| 82 | "s::" | ||
| 83 | #endif | ||
| 84 | #ifdef RLIMIT_CORE | ||
| 85 | "c::" | ||
| 86 | #endif | ||
| 87 | #ifdef RLIMIT_RSS | ||
| 88 | "m::" | ||
| 89 | #endif | ||
| 90 | #ifdef RLIMIT_MEMLOCK | ||
| 91 | "l::" | ||
| 92 | #endif | ||
| 93 | #ifdef RLIMIT_NPROC | ||
| 94 | "p::" | ||
| 95 | #endif | ||
| 96 | #ifdef RLIMIT_NOFILE | ||
| 97 | "n::" | ||
| 98 | #endif | ||
| 99 | #ifdef RLIMIT_AS | ||
| 100 | "v::" | ||
| 101 | #endif | ||
| 102 | #ifdef RLIMIT_LOCKS | ||
| 103 | "w::" | ||
| 104 | #endif | ||
| 105 | ; | ||
| 106 | |||
| 107 | static void printlim(unsigned opts, const struct rlimit *limit, | ||
| 108 | const struct limits *l) | ||
| 109 | { | ||
| 110 | rlim_t val; | ||
| 111 | |||
| 112 | val = limit->rlim_max; | ||
| 113 | if (!(opts & OPT_hard)) | ||
| 114 | val = limit->rlim_cur; | ||
| 115 | |||
| 116 | if (val == RLIM_INFINITY) | ||
| 117 | printf("unlimited\n"); | ||
| 118 | else { | ||
| 119 | val >>= l->factor_shift; | ||
| 120 | printf("%llu\n", (long long) val); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | int FAST_FUNC shell_builtin_ulimit(char **argv) | ||
| 125 | { | ||
| 126 | unsigned opts; | ||
| 127 | unsigned argc; | ||
| 128 | |||
| 129 | /* We can't use getopt32: need to handle commands like | ||
| 130 | * ulimit 123 -c2 -l 456 | ||
| 131 | */ | ||
| 132 | |||
| 133 | /* In case getopt was already called: | ||
| 134 | * reset the libc getopt() function, which keeps internal state. | ||
| 135 | */ | ||
| 136 | #ifdef __GLIBC__ | ||
| 137 | optind = 0; | ||
| 138 | #else /* BSD style */ | ||
| 139 | optind = 1; | ||
| 140 | /* optreset = 1; */ | ||
| 141 | #endif | ||
| 142 | /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ | ||
| 143 | |||
| 144 | argc = 1; | ||
| 145 | while (argv[argc]) | ||
| 146 | argc++; | ||
| 147 | |||
| 148 | opts = 0; | ||
| 149 | while (1) { | ||
| 150 | struct rlimit limit; | ||
| 151 | const struct limits *l; | ||
| 152 | int opt_char = getopt(argc, argv, ulimit_opt_string); | ||
| 153 | |||
| 154 | if (opt_char == -1) | ||
| 155 | break; | ||
| 156 | if (opt_char == 'H') { | ||
| 157 | opts |= OPT_hard; | ||
| 158 | continue; | ||
| 159 | } | ||
| 160 | if (opt_char == 'S') { | ||
| 161 | opts |= OPT_soft; | ||
| 162 | continue; | ||
| 163 | } | ||
| 164 | |||
| 165 | if (opt_char == 'a') { | ||
| 166 | for (l = limits_tbl; l != &limits_tbl[ARRAY_SIZE(limits_tbl)]; l++) { | ||
| 167 | getrlimit(l->cmd, &limit); | ||
| 168 | printf("-%c: %-30s ", l->option, l->name); | ||
| 169 | printlim(opts, &limit, l); | ||
| 170 | } | ||
| 171 | continue; | ||
| 172 | } | ||
| 173 | |||
| 174 | if (opt_char == 1) | ||
| 175 | opt_char = 'f'; | ||
| 176 | for (l = limits_tbl; l != &limits_tbl[ARRAY_SIZE(limits_tbl)]; l++) { | ||
| 177 | if (opt_char == l->option) { | ||
| 178 | char *val_str = optarg ? optarg : (argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL); | ||
| 179 | |||
| 180 | getrlimit(l->cmd, &limit); | ||
| 181 | if (val_str) { | ||
| 182 | rlim_t val; | ||
| 183 | |||
| 184 | if (!optarg) /* -c NNN: make getopt skip NNN */ | ||
| 185 | optind++; | ||
| 186 | |||
| 187 | if (strcmp(val_str, "unlimited") == 0) | ||
| 188 | val = RLIM_INFINITY; | ||
| 189 | else { | ||
| 190 | if (sizeof(val) == sizeof(int)) | ||
| 191 | val = bb_strtou(val_str, NULL, 10); | ||
| 192 | else if (sizeof(val) == sizeof(long)) | ||
| 193 | val = bb_strtoul(val_str, NULL, 10); | ||
| 194 | else | ||
| 195 | val = bb_strtoull(val_str, NULL, 10); | ||
| 196 | if (errno) { | ||
| 197 | bb_error_msg("bad number"); | ||
| 198 | return EXIT_FAILURE; | ||
| 199 | } | ||
| 200 | val <<= l->factor_shift; | ||
| 201 | } | ||
| 202 | //bb_error_msg("opt %c val_str:'%s' val:%lld", opt_char, val_str, (long long)val); | ||
| 203 | if (opts & OPT_hard) | ||
| 204 | limit.rlim_max = val; | ||
| 205 | if ((opts & OPT_soft) || opts == 0) | ||
| 206 | limit.rlim_cur = val; | ||
| 207 | //bb_error_msg("setrlimit(%d, %lld, %lld)", l->cmd, (long long)limit.rlim_cur, (long long)limit.rlim_max); | ||
| 208 | if (setrlimit(l->cmd, &limit) < 0) { | ||
| 209 | bb_perror_msg("error setting limit"); | ||
| 210 | return EXIT_FAILURE; | ||
| 211 | } | ||
| 212 | } else { | ||
| 213 | printlim(opts, &limit, l); | ||
| 214 | } | ||
| 215 | break; | ||
| 216 | } | ||
| 217 | } /* for (every possible opt) */ | ||
| 218 | |||
| 219 | if (l == &limits_tbl[ARRAY_SIZE(limits_tbl)]) { | ||
| 220 | /* bad option. getopt already complained. */ | ||
| 221 | break; | ||
| 222 | } | ||
| 223 | |||
| 224 | } /* while (there are options) */ | ||
| 225 | |||
| 226 | return 0; | ||
| 227 | } | ||
diff --git a/shell/builtin_ulimit.h b/shell/builtin_ulimit.h new file mode 100644 index 000000000..ec1af78a6 --- /dev/null +++ b/shell/builtin_ulimit.h | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * Adapted from ash applet code | ||
| 4 | * | ||
| 5 | * Copyright (c) 2010 Tobias Klauser | ||
| 6 | * Split from ash.c and slightly adapted. | ||
| 7 | * | ||
| 8 | * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. | ||
| 9 | */ | ||
| 10 | #ifndef SHELL_BUILTIN_ULIMIT_H | ||
| 11 | #define SHELL_BUILTIN_ULIMIT_H 1 | ||
| 12 | |||
| 13 | PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | ||
| 14 | |||
| 15 | int FAST_FUNC shell_builtin_ulimit(char **argv); | ||
| 16 | |||
| 17 | POP_SAVED_FUNCTION_VISIBILITY | ||
| 18 | |||
| 19 | #endif | ||
diff --git a/shell/hush.c b/shell/hush.c index 0310b02ed..6f391b881 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -57,7 +57,6 @@ | |||
| 57 | * | 57 | * |
| 58 | * TODOs: | 58 | * TODOs: |
| 59 | * grep for "TODO" and fix (some of them are easy) | 59 | * grep for "TODO" and fix (some of them are easy) |
| 60 | * builtins: ulimit | ||
| 61 | * special variables (done: PWD) | 60 | * special variables (done: PWD) |
| 62 | * follow IFS rules more precisely, including update semantics | 61 | * follow IFS rules more precisely, including update semantics |
| 63 | * export builtin should be special, its arguments are assignments | 62 | * export builtin should be special, its arguments are assignments |
| @@ -87,6 +86,7 @@ | |||
| 87 | 86 | ||
| 88 | #include "shell_common.h" | 87 | #include "shell_common.h" |
| 89 | #include "builtin_read.h" | 88 | #include "builtin_read.h" |
| 89 | #include "builtin_ulimit.h" | ||
| 90 | #include "math.h" | 90 | #include "math.h" |
| 91 | #include "match.h" | 91 | #include "match.h" |
| 92 | #if ENABLE_HUSH_RANDOM_SUPPORT | 92 | #if ENABLE_HUSH_RANDOM_SUPPORT |
| @@ -671,7 +671,7 @@ static const struct built_in_command bltins1[] = { | |||
| 671 | BLTIN("shift" , builtin_shift , "Shift positional parameters"), | 671 | BLTIN("shift" , builtin_shift , "Shift positional parameters"), |
| 672 | BLTIN("trap" , builtin_trap , "Trap signals"), | 672 | BLTIN("trap" , builtin_trap , "Trap signals"), |
| 673 | BLTIN("type" , builtin_type , "Write a description of command type"), | 673 | BLTIN("type" , builtin_type , "Write a description of command type"), |
| 674 | // BLTIN("ulimit" , builtin_ulimit , "Control resource limits"), | 674 | BLTIN("ulimit" , shell_builtin_ulimit , "Control resource limits"), |
| 675 | BLTIN("umask" , builtin_umask , "Set file creation mask"), | 675 | BLTIN("umask" , builtin_umask , "Set file creation mask"), |
| 676 | BLTIN("unset" , builtin_unset , "Unset variables"), | 676 | BLTIN("unset" , builtin_unset , "Unset variables"), |
| 677 | BLTIN("wait" , builtin_wait , "Wait for process"), | 677 | BLTIN("wait" , builtin_wait , "Wait for process"), |
