1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * ulimit builtin
32 */
33
34 #include <sys/resource.h>
35 #include <stdlib.h>
36 #include "defs.h"
37
38 /*
39 * order is important in this table! it is indexed by resource ID.
40 */
41
42 static struct rlimtab {
43 char *name;
44 char *scale;
45 rlim_t divisor;
46 } rlimtab[] = {
47 /* RLIMIT_CPU */ "time", "seconds", 1,
48 /* RLIMIT_FSIZE */ "file", "blocks", 512,
49 /* RLIMIT_DATA */ "data", "kbytes", 1024,
50 /* RLIMIT_STACK */ "stack", "kbytes", 1024,
51 /* RLIMIT_CORE */ "coredump", "blocks", 512,
52 /* RLIMIT_NOFILE */ "nofiles", "descriptors", 1,
53 /* RLIMIT_VMEM */ "memory", "kbytes", 1024,
54 };
55
56 void
sysulimit(int argc,char ** argv)57 sysulimit(int argc, char **argv)
58 {
59 extern int opterr, optind;
60 int savopterr, savoptind, savsp;
61 char *savoptarg;
62 char *args;
63 char errargs[PATH_MAX];
64 int hard, soft, cnt, c, res;
65 rlim_t limit, new_limit;
66 struct rlimit rlimit;
67 char resources[RLIM_NLIMITS];
68
69 for (res = 0; res < RLIM_NLIMITS; res++) {
70 resources[res] = 0;
71 }
72
73 savoptind = optind;
74 savopterr = opterr;
75 savsp = _sp;
76 savoptarg = optarg;
77 optind = 1;
78 _sp = 1;
79 opterr = 0;
80 hard = 0;
81 soft = 0;
82 cnt = 0;
83
84 while ((c = getopt(argc, argv, "HSacdfnstv")) != -1) {
85 switch (c) {
86 case 'S':
87 soft++;
88 continue;
89 case 'H':
90 hard++;
91 continue;
92 case 'a':
93 for (res = 0; res < RLIM_NLIMITS; res++) {
94 resources[res]++;
95 }
96 cnt = RLIM_NLIMITS;
97 continue;
98 case 'c':
99 res = RLIMIT_CORE;
100 break;
101 case 'd':
102 res = RLIMIT_DATA;
103 break;
104 case 'f':
105 res = RLIMIT_FSIZE;
106 break;
107 case 'n':
108 res = RLIMIT_NOFILE;
109 break;
110 case 's':
111 res = RLIMIT_STACK;
112 break;
113 case 't':
114 res = RLIMIT_CPU;
115 break;
116 case 'v':
117 res = RLIMIT_VMEM;
118 break;
119 case '?':
120 gfailure(usage, ulimuse);
121 goto err;
122 }
123 resources[res]++;
124 cnt++;
125 }
126
127 if (cnt == 0) {
128 resources[res = RLIMIT_FSIZE]++;
129 cnt++;
130 }
131
132 /*
133 * if out of arguments, then print the specified resources
134 */
135
136 if (optind == argc) {
137 if (!hard && !soft) {
138 soft++;
139 }
140 for (res = 0; res < RLIM_NLIMITS; res++) {
141 if (resources[res] == 0) {
142 continue;
143 }
144 if (getrlimit(res, &rlimit) < 0) {
145 continue;
146 }
147 if (cnt > 1) {
148 prs_buff(_gettext(rlimtab[res].name));
149 prc_buff('(');
150 prs_buff(_gettext(rlimtab[res].scale));
151 prc_buff(')');
152 prc_buff(' ');
153 }
154 if (soft) {
155 if (rlimit.rlim_cur == RLIM_INFINITY) {
156 prs_buff(_gettext("unlimited"));
157 } else {
158 prull_buff(rlimit.rlim_cur /
159 rlimtab[res].divisor);
160 }
161 }
162 if (hard && soft) {
163 prc_buff(':');
164 }
165 if (hard) {
166 if (rlimit.rlim_max == RLIM_INFINITY) {
167 prs_buff(_gettext("unlimited"));
168 } else {
169 prull_buff(rlimit.rlim_max /
170 rlimtab[res].divisor);
171 }
172 }
173 prc_buff('\n');
174 }
175 goto err;
176 }
177
178 if (cnt > 1 || optind + 1 != argc) {
179 gfailure(usage, ulimuse);
180 goto err;
181 }
182
183 if (eq(argv[optind], "unlimited")) {
184 limit = RLIM_INFINITY;
185 } else {
186 args = argv[optind];
187
188 new_limit = limit = 0;
189 do {
190 if (*args < '0' || *args > '9') {
191 snprintf(errargs, PATH_MAX-1,
192 "%s: %s", argv[0], args);
193 failure(errargs, badnum);
194 goto err;
195 }
196 /* Check for overflow! */
197 new_limit = (limit * 10) + (*args - '0');
198 if (new_limit >= limit) {
199 limit = new_limit;
200 } else {
201 snprintf(errargs, PATH_MAX-1,
202 "%s: %s", argv[0], args);
203 failure(errargs, badnum);
204 goto err;
205 }
206 } while (*++args);
207
208 /* Check for overflow! */
209 new_limit = limit * rlimtab[res].divisor;
210 if (new_limit >= limit) {
211 limit = new_limit;
212 } else {
213 snprintf(errargs, PATH_MAX-1,
214 "%s: %s", argv[0], args);
215 failure(errargs, badnum);
216 goto err;
217 }
218 }
219
220 if (getrlimit(res, &rlimit) < 0) {
221 failure(argv[0], badnum);
222 goto err;
223 }
224
225 if (!hard && !soft) {
226 hard++;
227 soft++;
228 }
229 if (hard) {
230 rlimit.rlim_max = limit;
231 }
232 if (soft) {
233 rlimit.rlim_cur = limit;
234 }
235
236 if (setrlimit(res, &rlimit) < 0) {
237 snprintf(errargs, PATH_MAX-1,
238 "%s: %s", argv[0], argv[optind]);
239 failure(errargs, badulimit);
240 }
241
242 err:
243 optind = savoptind;
244 opterr = savopterr;
245 _sp = savsp;
246 optarg = savoptarg;
247 }
248