2 * Asterisk -- A telephony toolkit for Linux.
6 * Copyright (c) 2006 Tilghman Lesher. All rights reserved.
8 * Tilghman Lesher <res_limit_200607@the-tilghman.com>
10 * This code is released by the author with no restrictions on usage.
19 #define _XOPEN_SOURCE 600
23 #include <sys/resource.h>
25 #include "asterisk/module.h"
26 #include "asterisk/cli.h"
28 /* Find proper rlimit for virtual memory */
30 #define VMEM_DEF RLIMIT_AS
33 #define VMEM_DEF RLIMIT_VMEM
37 static struct limits {
42 { RLIMIT_CPU, "-t", "cpu time" },
43 { RLIMIT_FSIZE, "-f", "file size" },
44 { RLIMIT_DATA, "-d", "program data segment" },
45 { RLIMIT_STACK, "-s", "program stack size" },
46 { RLIMIT_CORE, "-c", "core file size" },
48 { RLIMIT_RSS, "-m", "resident memory" },
49 { RLIMIT_NPROC, "-u", "number of processes" },
50 { RLIMIT_MEMLOCK, "-l", "amount of memory locked into RAM" },
52 { RLIMIT_NOFILE, "-n", "number of file descriptors" },
54 { VMEM_DEF, "-v", "virtual memory" },
58 static int str2limit(const char *string)
61 for (i = 0; i < sizeof(limits) / sizeof(limits[0]); i++) {
62 if (!strcasecmp(string, limits[i].limit))
63 return limits[i].resource;
68 static const char *str2desc(const char *string)
71 for (i = 0; i < sizeof(limits) / sizeof(limits[0]); i++) {
72 if (!strcmp(string, limits[i].limit))
73 return limits[i].desc;
78 static int my_ulimit(int fd, int argc, char **argv)
81 struct rlimit rlimit = { 0, 0 };
83 return RESULT_SHOWUSAGE;
87 char *newargv[2] = { "ulimit", arg2 };
88 for (resource = 0; resource < sizeof(limits) / sizeof(limits[0]); resource++) {
89 ast_copy_string(arg2, limits[resource].limit, sizeof(arg2));
90 my_ulimit(fd, 2, newargv);
92 return RESULT_SUCCESS;
94 resource = str2limit(argv[1]);
96 ast_cli(fd, "Unknown resource\n");
97 return RESULT_FAILURE;
102 if (resource != RLIMIT_NOFILE && resource != RLIMIT_CORE && resource != RLIMIT_NPROC && resource != RLIMIT_FSIZE) {
103 ast_cli(fd, "Resource not permitted to be set\n");
104 return RESULT_FAILURE;
107 sscanf(argv[2], "%d", &x);
108 rlimit.rlim_max = rlimit.rlim_cur = x;
109 setrlimit(resource, &rlimit);
110 return RESULT_SUCCESS;
112 if (!getrlimit(resource, &rlimit)) {
115 if (rlimit.rlim_max == RLIM_INFINITY)
116 ast_copy_string(printlimit, "effectively unlimited", sizeof(printlimit));
118 snprintf(printlimit, sizeof(printlimit), "limited to %d", (int)rlimit.rlim_cur);
119 desc = str2desc(argv[1]);
120 ast_cli(fd, "%c%s (%s) is %s.\n", toupper(desc[0]), desc + 1, argv[1], printlimit);
122 ast_cli(fd, "Could not retrieve resource limits for %s: %s\n", str2desc(argv[1]), strerror(errno));
123 return RESULT_SUCCESS;
128 static char *complete_ulimit(const char *line, const char *word, int pos, int state)
131 int wordlen = strlen(word);
135 for (i = 0; i < sizeof(limits) / sizeof(limits[0]); i++) {
136 if (!strncasecmp(limits[i].limit, word, wordlen)) {
138 return ast_strdup(limits[i].limit);
144 static const char ulimit_usage[] =
145 "Usage: ulimit {-d|-l|-f|-m|-s|-t|-u|-v|-c|-n} [<num>]\n"
146 " Shows or sets the corresponding resource limit.\n"
147 " -d Process data segment [readonly]\n"
148 " -l Memory lock size [readonly]\n"
150 " -m Process resident memory [readonly]\n"
151 " -s Process stack size [readonly]\n"
152 " -t CPU usage [readonly]\n"
153 " -u Child processes\n"
155 " -v Process virtual memory [readonly]\n"
157 " -c Core dump file size\n"
158 " -n Number of file descriptors\n";
160 static struct ast_cli_entry cli_ulimit = {
161 { "ulimit", NULL }, my_ulimit,
162 "Set or show process resource limits", ulimit_usage, complete_ulimit };
164 static int unload_module(void)
166 return ast_cli_unregister(&cli_ulimit);
169 static int load_module(void)
171 return ast_cli_register(&cli_ulimit)? AST_MODULE_LOAD_FAILURE: AST_MODULE_LOAD_SUCCESS;
174 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Resource limits");