summaryrefslogtreecommitdiff
path: root/shell/ash.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/ash.c')
-rw-r--r--shell/ash.c214
1 files changed, 3 insertions, 211 deletions
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 */
12626struct 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
12632static 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};
12667static 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
12703enum limtype { SOFT = 0x1, HARD = 0x2 };
12704
12705static void
12706printlim(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
12723static int FAST_FUNC 12618static int FAST_FUNC
12724ulimitcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) 12619ulimitcmd(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 */