~emersion/mrsh

ref: 41bcddb91a9ab4fa0c5ae2e53cdf9a3a8b4ef10c mrsh/builtin/ulimit.c -rw-r--r-- 1.6 KiB View raw
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#define _POSIX_C_SOURCE 200809L
#include <mrsh/getopt.h>
#include <mrsh/shell.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <sys/time.h>
#include <sys/resource.h>
#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;
}