From 41bcddb91a9ab4fa0c5ae2e53cdf9a3a8b4ef10c Mon Sep 17 00:00:00 2001 From: Julian P Samaroo Date: Tue, 8 Jan 2019 16:00:06 -0600 Subject: [PATCH] Implemented ulimit builtin --- builtin/builtin.c | 1 + builtin/ulimit.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++ include/builtin.h | 1 + meson.build | 1 + test/meson.build | 5 ++-- test/ulimit.sh | 19 ++++++++++++++ 6 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 builtin/ulimit.c create mode 100644 test/ulimit.sh diff --git a/builtin/builtin.c b/builtin/builtin.c index 2692532..f54e95f 100644 --- a/builtin/builtin.c +++ b/builtin/builtin.c @@ -31,6 +31,7 @@ static const struct builtin builtins[] = { { "times", builtin_times, true }, { "true", builtin_true, false }, { "type", builtin_type, false }, + { "ulimit", builtin_ulimit, false }, { "umask", builtin_umask, false }, { "unalias", builtin_unalias, false }, { "unset", builtin_unset, true }, diff --git a/builtin/ulimit.c b/builtin/ulimit.c new file mode 100644 index 0000000..f9573d9 --- /dev/null +++ b/builtin/ulimit.c @@ -0,0 +1,66 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "builtin.h" + +static const char ulimit_usage[] = "usage: ulimit [-f] [blocks]\n"; + +int builtin_ulimit(struct mrsh_state *state, int argc, char *argv[]) { + mrsh_optind = 1; + int opt; + while ((opt = mrsh_getopt(argc, argv, ":f")) != -1) { + if (opt == 'f') { + // Nothing here + } else { + fprintf(stderr, "%s", ulimit_usage); + return EXIT_FAILURE; + } + } + + if (mrsh_optind == argc - 1) { + errno = 0; + char *arg = argv[mrsh_optind]; + char *endptr; + long int new_limit = strtol(arg, &endptr, 10); + if (errno != 0) { + fprintf(stderr, "strtol error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + if ((endptr == arg) || (endptr[0] != '\0')) { + fprintf(stderr, "ulimit error: Invalid argument: %s\n", + arg); + return EXIT_FAILURE; + } + struct rlimit new = { + .rlim_cur = new_limit * 512, + .rlim_max = new_limit * 512 + }; + if (setrlimit(RLIMIT_FSIZE, &new) != 0) { + fprintf(stderr, "setrlimit error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + } else if (mrsh_optind == argc) { + struct rlimit old = { 0 }; + if (getrlimit(RLIMIT_FSIZE, &old) != 0) { + fprintf(stderr, "getrlimit error: %s\n", strerror(errno)); + return EXIT_FAILURE; + } + if (old.rlim_max == RLIM_INFINITY) { + printf("unlimited\n"); + } else { + printf("%lu\n", old.rlim_max / 512); + } + } else { + fprintf(stderr, "%s", ulimit_usage); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/include/builtin.h b/include/builtin.h index ed437b2..afebdc4 100644 --- a/include/builtin.h +++ b/include/builtin.h @@ -24,6 +24,7 @@ int builtin_shift(struct mrsh_state *state, int argc, char *argv[]); int builtin_times(struct mrsh_state *state, int argc, char *argv[]); int builtin_true(struct mrsh_state *state, int argc, char *argv[]); int builtin_type(struct mrsh_state *state, int argc, char *argv[]); +int builtin_ulimit(struct mrsh_state *state, int argc, char *argv[]); int builtin_umask(struct mrsh_state *state, int argc, char *argv[]); int builtin_unalias(struct mrsh_state *state, int argc, char *argv[]); int builtin_unset(struct mrsh_state *state, int argc, char *argv[]); diff --git a/meson.build b/meson.build index 5b00c3b..c2c396e 100644 --- a/meson.build +++ b/meson.build @@ -64,6 +64,7 @@ lib_mrsh = library( 'builtin/times.c', 'builtin/true.c', 'builtin/type.c', + 'builtin/ulimit.c', 'builtin/umask.c', 'builtin/unalias.c', 'builtin/unset.c', diff --git a/test/meson.build b/test/meson.build index b429be4..4f74e3d 100644 --- a/test/meson.build +++ b/test/meson.build @@ -5,11 +5,12 @@ test_files = [ 'conformance/if.sh', 'case.sh', + 'for.sh', + 'function.sh', 'loop.sh', 'subshell.sh', + 'ulimit.sh', 'word.sh', - 'for.sh', - 'function.sh', ] foreach test_file : test_files diff --git a/test/ulimit.sh b/test/ulimit.sh new file mode 100644 index 0000000..70adffc --- /dev/null +++ b/test/ulimit.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +set -e + +mrsh_limits=`ulimit` +[ $mrsh_limits == "unlimited" ] +if [ -e /proc/self/limits ] +then + grep "Max file size" /proc/self/limits | grep "unlimited" +fi + +ulimit -f 100 + +mrsh_limits=`ulimit` +[ $mrsh_limits -eq 100 ] +if [ -e /proc/self/limits ] +then + grep "Max file size" /proc/self/limits | grep 51200 +fi -- 2.26.2