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 #pragma ident "%Z%%M% %I% %E% SMI"
32
33 /*
34 * ulimit builtin
35 */
36
37 #include <sys/resource.h>
38 #include <stdlib.h>
39 #include "defs.h"
40
41 /*
42 * order is important in this table! it is indexed by resource ID.
43 */
44
45 static struct rlimtab {
46 char *name;
47 char *scale;
48 rlim_t divisor;
49 } rlimtab[] = {
50 /* RLIMIT_CPU */ "time", "seconds", 1,
51 /* RLIMIT_FSIZE */ "file", "blocks", 512,
52 /* RLIMIT_DATA */ "data", "kbytes", 1024,
53 /* RLIMIT_STACK */ "stack", "kbytes", 1024,
54 /* RLIMIT_CORE */ "coredump", "blocks", 512,
55 /* RLIMIT_NOFILE */ "nofiles", "descriptors", 1,
56 /* RLIMIT_VMEM */ "memory", "kbytes", 1024,
57 };
58
59 void
sysulimit(int argc,char ** argv)60 sysulimit(int argc, char **argv)
61 {
62 extern int opterr, optind;
63 int savopterr, savoptind, savsp;
64 char *savoptarg;
65 char *args;
66 char errargs[PATH_MAX];
67 int hard, soft, cnt, c, res;
68 rlim_t limit, new_limit;
69 struct rlimit rlimit;
70 char resources[RLIM_NLIMITS];
71
72 for (res = 0; res < RLIM_NLIMITS; res++) {
73 resources[res] = 0;
74 }
75
76 savoptind = optind;
77 savopterr = opterr;
78 savsp = _sp;
79 savoptarg = optarg;
80 optind = 1;
81 _sp = 1;
82 opterr = 0;
83 hard = 0;
84 soft = 0;
85 cnt = 0;
86
87 while ((c = getopt(argc, argv, "HSacdfnstv")) != -1) {
88 switch (c) {
89 case 'S':
90 soft++;
91 continue;
92 case 'H':
93 hard++;
94 continue;
95 case 'a':
96 for (res = 0; res < RLIM_NLIMITS; res++) {
97 resources[res]++;
98 }
99 cnt = RLIM_NLIMITS;
100 continue;
101 case 'c':
102 res = RLIMIT_CORE;
103 break;
104 case 'd':
105 res = RLIMIT_DATA;
106 break;
107 case 'f':
108 res = RLIMIT_FSIZE;
109 break;
110 case 'n':
111 res = RLIMIT_NOFILE;
112 break;
113 case 's':
114 res = RLIMIT_STACK;
115 break;
116 case 't':
117 res = RLIMIT_CPU;
118 break;
119 case 'v':
120 res = RLIMIT_VMEM;
121 break;
122 case '?':
123 gfailure(usage, ulimuse);
124 goto err;
125 }
126 resources[res]++;
127 cnt++;
128 }
129
130 if (cnt == 0) {
131 resources[res = RLIMIT_FSIZE]++;
132 cnt++;
133 }
134
135 /*
136 * if out of arguments, then print the specified resources
137 */
138
139 if (optind == argc) {
140 if (!hard && !soft) {
141 soft++;
142 }
143 for (res = 0; res < RLIM_NLIMITS; res++) {
144 if (resources[res] == 0) {
145 continue;
146 }
147 if (getrlimit(res, &rlimit) < 0) {
148 continue;
149 }
150 if (cnt > 1) {
151 prs_buff(_gettext(rlimtab[res].name));
152 prc_buff('(');
153 prs_buff(_gettext(rlimtab[res].scale));
154 prc_buff(')');
155 prc_buff(' ');
156 }
157 if (soft) {
158 if (rlimit.rlim_cur == RLIM_INFINITY) {
159 prs_buff(_gettext("unlimited"));
160 } else {
161 prull_buff(rlimit.rlim_cur /
162 rlimtab[res].divisor);
163 }
164 }
165 if (hard && soft) {
166 prc_buff(':');
167 }
168 if (hard) {
169 if (rlimit.rlim_max == RLIM_INFINITY) {
170 prs_buff(_gettext("unlimited"));
171 } else {
172 prull_buff(rlimit.rlim_max /
173 rlimtab[res].divisor);
174 }
175 }
176 prc_buff('\n');
177 }
178 goto err;
179 }
180
181 if (cnt > 1 || optind + 1 != argc) {
182 gfailure(usage, ulimuse);
183 goto err;
184 }
185
186 if (eq(argv[optind], "unlimited")) {
187 limit = RLIM_INFINITY;
188 } else {
189 args = argv[optind];
190
191 new_limit = limit = 0;
192 do {
193 if (*args < '0' || *args > '9') {
194 snprintf(errargs, PATH_MAX-1,
195 "%s: %s", argv[0], args);
196 failure(errargs, badnum);
197 goto err;
198 }
199 /* Check for overflow! */
200 new_limit = (limit * 10) + (*args - '0');
201 if (new_limit >= limit) {
202 limit = new_limit;
203 } else {
204 snprintf(errargs, PATH_MAX-1,
205 "%s: %s", argv[0], args);
206 failure(errargs, badnum);
207 goto err;
208 }
209 } while (*++args);
210
211 /* Check for overflow! */
212 new_limit = limit * rlimtab[res].divisor;
213 if (new_limit >= limit) {
214 limit = new_limit;
215 } else {
216 snprintf(errargs, PATH_MAX-1,
217 "%s: %s", argv[0], args);
218 failure(errargs, badnum);
219 goto err;
220 }
221 }
222
223 if (getrlimit(res, &rlimit) < 0) {
224 failure(argv[0], badnum);
225 goto err;
226 }
227
228 if (!hard && !soft) {
229 hard++;
230 soft++;
231 }
232 if (hard) {
233 rlimit.rlim_max = limit;
234 }
235 if (soft) {
236 rlimit.rlim_cur = limit;
237 }
238
239 if (setrlimit(res, &rlimit) < 0) {
240 snprintf(errargs, PATH_MAX-1,
241 "%s: %s", argv[0], argv[optind]);
242 failure(errargs, badulimit);
243 }
244
245 err:
246 optind = savoptind;
247 opterr = savopterr;
248 _sp = savsp;
249 optarg = savoptarg;
250 }
251