xref: /titanic_41/usr/src/cmd/sh/ulimit.c (revision d89fccd8788afe1e920f842edd883fe192a1b8fe)
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  /*
23   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24   * Use is subject to license terms.
25   */
26  /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27  /*	  All Rights Reserved  	*/
28  
29  
30  #pragma ident	"%Z%%M%	%I%	%E% SMI"
31  
32  /*
33   * ulimit builtin
34   */
35  
36  #include <sys/resource.h>
37  #include <stdlib.h>
38  #include "defs.h"
39  
40  /*
41   * order is important in this table! it is indexed by resource ID.
42   */
43  
44  static struct rlimtab {
45  	char	*name;
46  	char	*scale;
47  	rlim_t	divisor;
48  } rlimtab[] = {
49  /* RLIMIT_CPU	*/	"time",		"seconds",	1,
50  /* RLIMIT_FSIZE */	"file",		"blocks",	512,
51  /* RLIMIT_DATA	*/	"data",		"kbytes",	1024,
52  /* RLIMIT_STACK */	"stack",	"kbytes",	1024,
53  /* RLIMIT_CORE	*/	"coredump",	"blocks",	512,
54  /* RLIMIT_NOFILE */	"nofiles",	"descriptors",	1,
55  /* RLIMIT_VMEM */	"memory",	"kbytes",	1024,
56  };
57  
58  void
59  sysulimit(int argc, char **argv)
60  {
61  	extern int opterr, optind;
62  	int savopterr, savoptind, savsp;
63  	char *savoptarg;
64  	char *args;
65  	char errargs[PATH_MAX];
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  				snprintf(errargs, PATH_MAX-1,
194  				"%s: %s", argv[0], args);
195  				failure(errargs, badnum);
196  				goto err;
197  			}
198  			/* Check for overflow! */
199  			new_limit = (limit * 10) + (*args - '0');
200  			if (new_limit >= limit) {
201  				limit = new_limit;
202  			} else {
203  				snprintf(errargs, PATH_MAX-1,
204  				"%s: %s", argv[0], args);
205  				failure(errargs, badnum);
206  				goto err;
207  			}
208  		} while (*++args);
209  
210  		/* Check for overflow! */
211  		new_limit = limit * rlimtab[res].divisor;
212  		if (new_limit >= limit) {
213  			limit = new_limit;
214  		} else {
215  			snprintf(errargs, PATH_MAX-1,
216  			"%s: %s", argv[0], args);
217  			failure(errargs, badnum);
218  			goto err;
219  		}
220  	}
221  
222  	if (getrlimit(res, &rlimit) < 0) {
223  		failure(argv[0], badnum);
224  		goto err;
225  	}
226  
227  	if (!hard && !soft) {
228  		hard++;
229  		soft++;
230  	}
231  	if (hard) {
232  		rlimit.rlim_max = limit;
233  	}
234  	if (soft) {
235  		rlimit.rlim_cur = limit;
236  	}
237  
238  	if (setrlimit(res, &rlimit) < 0) {
239  		snprintf(errargs, PATH_MAX-1,
240  		"%s: %s", argv[0], argv[optind]);
241  		failure(errargs, badulimit);
242  	}
243  
244  err:
245  	optind = savoptind;
246  	opterr = savopterr;
247  	_sp = savsp;
248  	optarg = savoptarg;
249  }
250