xref: /titanic_52/usr/src/cmd/sh/ulimit.c (revision 1cb6af97c6f66f456d4f726ef056e1ebc0f73305)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 
26 /*
27  * Copyright (c) 1996,1997 by Sun Microsystems, Inc.
28  * All rights reserved.
29  */
30 
31 #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
60 sysulimit(int argc, char **argv)
61 {
62 	extern int opterr, optind;
63 	int savopterr, savoptind, savsp;
64 	char *savoptarg;
65 	char *args;
66 	int hard, soft, cnt, c, res;
67 	rlim_t limit, new_limit;
68 	struct rlimit rlimit;
69 	char resources[RLIM_NLIMITS];
70 
71 	for (res = 0;  res < RLIM_NLIMITS; res++) {
72 		resources[res] = 0;
73 	}
74 
75 	savoptind = optind;
76 	savopterr = opterr;
77 	savsp = _sp;
78 	savoptarg = optarg;
79 	optind = 1;
80 	_sp = 1;
81 	opterr = 0;
82 	hard = 0;
83 	soft = 0;
84 	cnt = 0;
85 
86 	while ((c = getopt(argc, argv, "HSacdfnstv")) != -1) {
87 		switch (c) {
88 		case 'S':
89 			soft++;
90 			continue;
91 		case 'H':
92 			hard++;
93 			continue;
94 		case 'a':
95 			for (res = 0;  res < RLIM_NLIMITS; res++) {
96 				resources[res]++;
97 			}
98 			cnt = RLIM_NLIMITS;
99 			continue;
100 		case 'c':
101 			res = RLIMIT_CORE;
102 			break;
103 		case 'd':
104 			res = RLIMIT_DATA;
105 			break;
106 		case 'f':
107 			res = RLIMIT_FSIZE;
108 			break;
109 		case 'n':
110 			res = RLIMIT_NOFILE;
111 			break;
112 		case 's':
113 			res = RLIMIT_STACK;
114 			break;
115 		case 't':
116 			res = RLIMIT_CPU;
117 			break;
118 		case 'v':
119 			res = RLIMIT_VMEM;
120 			break;
121 		case '?':
122 			failure(usage, ulimuse);
123 			goto err;
124 		}
125 		resources[res]++;
126 		cnt++;
127 	}
128 
129 	if (cnt == 0) {
130 		resources[res = RLIMIT_FSIZE]++;
131 		cnt++;
132 	}
133 
134 	/*
135 	 * if out of arguments, then print the specified resources
136 	 */
137 
138 	if (optind == argc) {
139 		if (!hard && !soft) {
140 			soft++;
141 		}
142 		for (res = 0; res < RLIM_NLIMITS; res++) {
143 			if (resources[res] == 0) {
144 				continue;
145 			}
146 			if (getrlimit(res, &rlimit) < 0) {
147 				continue;
148 			}
149 			if (cnt > 1) {
150 				prs_buff(rlimtab[res].name);
151 				prc_buff('(');
152 				prs_buff(rlimtab[res].scale);
153 				prc_buff(')');
154 				prc_buff(' ');
155 			}
156 			if (soft) {
157 				if (rlimit.rlim_cur == RLIM_INFINITY) {
158 					prs_buff("unlimited");
159 				} else  {
160 					prull_buff(rlimit.rlim_cur /
161 					    rlimtab[res].divisor);
162 				}
163 			}
164 			if (hard && soft) {
165 				prc_buff(':');
166 			}
167 			if (hard) {
168 				if (rlimit.rlim_max == RLIM_INFINITY) {
169 					prs_buff("unlimited");
170 				} else  {
171 					prull_buff(rlimit.rlim_max /
172 					    rlimtab[res].divisor);
173 				}
174 			}
175 			prc_buff('\n');
176 		}
177 		goto err;
178 	}
179 
180 	if (cnt > 1 || optind + 1 != argc) {
181 		failure(usage, ulimuse);
182 		goto err;
183 	}
184 
185 	if (eq(argv[optind], "unlimited")) {
186 		limit = RLIM_INFINITY;
187 	} else {
188 		args = argv[optind];
189 
190 		new_limit = limit = 0;
191 		do {
192 			if (*args < '0' || *args > '9') {
193 				failure(argv[0], badulimit);
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 				failure(argv[0], badulimit);
202 				goto err;
203 			}
204 		} while (*++args);
205 
206 		/* Check for overflow! */
207 		new_limit = limit * rlimtab[res].divisor;
208 		if (new_limit >= limit) {
209 			limit = new_limit;
210 		} else {
211 			failure(argv[0], badulimit);
212 			goto err;
213 		}
214 	}
215 
216 	if (getrlimit(res, &rlimit) < 0) {
217 		failure(argv[0], badulimit);
218 		goto err;
219 	}
220 
221 	if (!hard && !soft) {
222 		hard++;
223 		soft++;
224 	}
225 	if (hard) {
226 		rlimit.rlim_max = limit;
227 	}
228 	if (soft) {
229 		rlimit.rlim_cur = limit;
230 	}
231 
232 	if (setrlimit(res, &rlimit) < 0) {
233 		failure(argv[0], badulimit);
234 	}
235 
236 err:
237 	optind = savoptind;
238 	opterr = savopterr;
239 	_sp = savsp;
240 	optarg = savoptarg;
241 }
242