xref: /aosp_15_r20/external/mksh/src/ulimit.c (revision 7c356e860f31eadd15fd599fcfdb9fd21f16a9d4)
1*7c356e86SAndroid Build Coastguard Worker /*	$OpenBSD: c_ulimit.c,v 1.19 2013/11/28 10:33:37 sobrado Exp $	*/
2*7c356e86SAndroid Build Coastguard Worker 
3*7c356e86SAndroid Build Coastguard Worker /*-
4*7c356e86SAndroid Build Coastguard Worker  * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
5*7c356e86SAndroid Build Coastguard Worker  *		 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
6*7c356e86SAndroid Build Coastguard Worker  *		 2019, 2020
7*7c356e86SAndroid Build Coastguard Worker  *	mirabilos <[email protected]>
8*7c356e86SAndroid Build Coastguard Worker  *
9*7c356e86SAndroid Build Coastguard Worker  * Provided that these terms and disclaimer and all copyright notices
10*7c356e86SAndroid Build Coastguard Worker  * are retained or reproduced in an accompanying document, permission
11*7c356e86SAndroid Build Coastguard Worker  * is granted to deal in this work without restriction, including un-
12*7c356e86SAndroid Build Coastguard Worker  * limited rights to use, publicly perform, distribute, sell, modify,
13*7c356e86SAndroid Build Coastguard Worker  * merge, give away, or sublicence.
14*7c356e86SAndroid Build Coastguard Worker  *
15*7c356e86SAndroid Build Coastguard Worker  * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
16*7c356e86SAndroid Build Coastguard Worker  * the utmost extent permitted by applicable law, neither express nor
17*7c356e86SAndroid Build Coastguard Worker  * implied; without malicious intent or gross negligence. In no event
18*7c356e86SAndroid Build Coastguard Worker  * may a licensor, author or contributor be held liable for indirect,
19*7c356e86SAndroid Build Coastguard Worker  * direct, other damage, loss, or other issues arising in any way out
20*7c356e86SAndroid Build Coastguard Worker  * of dealing in the work, even if advised of the possibility of such
21*7c356e86SAndroid Build Coastguard Worker  * damage or existence of a defect, except proven that it results out
22*7c356e86SAndroid Build Coastguard Worker  * of said person's immediate fault when using the work as intended.
23*7c356e86SAndroid Build Coastguard Worker  */
24*7c356e86SAndroid Build Coastguard Worker 
25*7c356e86SAndroid Build Coastguard Worker #include "sh.h"
26*7c356e86SAndroid Build Coastguard Worker 
27*7c356e86SAndroid Build Coastguard Worker __RCSID("$MirOS: src/bin/mksh/ulimit.c,v 1.3 2020/07/24 21:08:26 tg Exp $");
28*7c356e86SAndroid Build Coastguard Worker 
29*7c356e86SAndroid Build Coastguard Worker #define SOFT	0x1
30*7c356e86SAndroid Build Coastguard Worker #define HARD	0x2
31*7c356e86SAndroid Build Coastguard Worker 
32*7c356e86SAndroid Build Coastguard Worker #if HAVE_RLIMIT
33*7c356e86SAndroid Build Coastguard Worker 
34*7c356e86SAndroid Build Coastguard Worker #if !HAVE_RLIM_T
35*7c356e86SAndroid Build Coastguard Worker typedef unsigned long rlim_t;
36*7c356e86SAndroid Build Coastguard Worker #endif
37*7c356e86SAndroid Build Coastguard Worker 
38*7c356e86SAndroid Build Coastguard Worker /* Magic to divine the 'm' and 'v' limits */
39*7c356e86SAndroid Build Coastguard Worker 
40*7c356e86SAndroid Build Coastguard Worker #ifdef RLIMIT_AS
41*7c356e86SAndroid Build Coastguard Worker #if !defined(RLIMIT_VMEM) || (RLIMIT_VMEM == RLIMIT_AS) || \
42*7c356e86SAndroid Build Coastguard Worker     !defined(RLIMIT_RSS) || (RLIMIT_VMEM == RLIMIT_RSS)
43*7c356e86SAndroid Build Coastguard Worker #define ULIMIT_V_IS_AS
44*7c356e86SAndroid Build Coastguard Worker #elif defined(RLIMIT_VMEM)
45*7c356e86SAndroid Build Coastguard Worker #if !defined(RLIMIT_RSS) || (RLIMIT_RSS == RLIMIT_AS)
46*7c356e86SAndroid Build Coastguard Worker #define ULIMIT_V_IS_AS
47*7c356e86SAndroid Build Coastguard Worker #else
48*7c356e86SAndroid Build Coastguard Worker #define ULIMIT_V_IS_VMEM
49*7c356e86SAndroid Build Coastguard Worker #endif
50*7c356e86SAndroid Build Coastguard Worker #endif
51*7c356e86SAndroid Build Coastguard Worker #endif
52*7c356e86SAndroid Build Coastguard Worker 
53*7c356e86SAndroid Build Coastguard Worker #ifdef RLIMIT_RSS
54*7c356e86SAndroid Build Coastguard Worker #ifdef ULIMIT_V_IS_VMEM
55*7c356e86SAndroid Build Coastguard Worker #define ULIMIT_M_IS_RSS
56*7c356e86SAndroid Build Coastguard Worker #elif defined(RLIMIT_VMEM) && (RLIMIT_VMEM == RLIMIT_RSS)
57*7c356e86SAndroid Build Coastguard Worker #define ULIMIT_M_IS_VMEM
58*7c356e86SAndroid Build Coastguard Worker #else
59*7c356e86SAndroid Build Coastguard Worker #define ULIMIT_M_IS_RSS
60*7c356e86SAndroid Build Coastguard Worker #endif
61*7c356e86SAndroid Build Coastguard Worker #if defined(ULIMIT_M_IS_RSS) && defined(RLIMIT_AS) && \
62*7c356e86SAndroid Build Coastguard Worker     !defined(__APPLE__) && (RLIMIT_RSS == RLIMIT_AS)
63*7c356e86SAndroid Build Coastguard Worker /* On Mac OSX keep -m as -v alias for pkgsrc and other software expecting it */
64*7c356e86SAndroid Build Coastguard Worker #undef ULIMIT_M_IS_RSS
65*7c356e86SAndroid Build Coastguard Worker #endif
66*7c356e86SAndroid Build Coastguard Worker #endif
67*7c356e86SAndroid Build Coastguard Worker 
68*7c356e86SAndroid Build Coastguard Worker #if !defined(RLIMIT_AS) && !defined(ULIMIT_M_IS_VMEM) && defined(RLIMIT_VMEM)
69*7c356e86SAndroid Build Coastguard Worker #define ULIMIT_V_IS_VMEM
70*7c356e86SAndroid Build Coastguard Worker #endif
71*7c356e86SAndroid Build Coastguard Worker 
72*7c356e86SAndroid Build Coastguard Worker #if !defined(ULIMIT_V_IS_VMEM) && defined(RLIMIT_VMEM) && \
73*7c356e86SAndroid Build Coastguard Worker     (!defined(RLIMIT_RSS) || (defined(RLIMIT_AS) && (RLIMIT_RSS == RLIMIT_AS)))
74*7c356e86SAndroid Build Coastguard Worker #define ULIMIT_M_IS_VMEM
75*7c356e86SAndroid Build Coastguard Worker #endif
76*7c356e86SAndroid Build Coastguard Worker 
77*7c356e86SAndroid Build Coastguard Worker #if defined(ULIMIT_M_IS_VMEM) && defined(RLIMIT_AS) && \
78*7c356e86SAndroid Build Coastguard Worker     (RLIMIT_VMEM == RLIMIT_AS)
79*7c356e86SAndroid Build Coastguard Worker #undef ULIMIT_M_IS_VMEM
80*7c356e86SAndroid Build Coastguard Worker #endif
81*7c356e86SAndroid Build Coastguard Worker 
82*7c356e86SAndroid Build Coastguard Worker #if defined(ULIMIT_M_IS_RSS) && defined(ULIMIT_M_IS_VMEM)
83*7c356e86SAndroid Build Coastguard Worker # error nonsensical m ulimit
84*7c356e86SAndroid Build Coastguard Worker #endif
85*7c356e86SAndroid Build Coastguard Worker 
86*7c356e86SAndroid Build Coastguard Worker #if defined(ULIMIT_V_IS_VMEM) && defined(ULIMIT_V_IS_AS)
87*7c356e86SAndroid Build Coastguard Worker # error nonsensical v ulimit
88*7c356e86SAndroid Build Coastguard Worker #endif
89*7c356e86SAndroid Build Coastguard Worker 
90*7c356e86SAndroid Build Coastguard Worker #define LIMITS_GEN	"rlimits.gen"
91*7c356e86SAndroid Build Coastguard Worker 
92*7c356e86SAndroid Build Coastguard Worker #else /* !HAVE_RLIMIT */
93*7c356e86SAndroid Build Coastguard Worker 
94*7c356e86SAndroid Build Coastguard Worker #undef RLIMIT_CORE	/* just in case */
95*7c356e86SAndroid Build Coastguard Worker 
96*7c356e86SAndroid Build Coastguard Worker #if defined(UL_GETFSIZE)
97*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_GFIL	UL_GETFSIZE
98*7c356e86SAndroid Build Coastguard Worker #elif defined(UL_GFILLIM)
99*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_GFIL	UL_GFILLIM
100*7c356e86SAndroid Build Coastguard Worker #elif defined(__A_UX__) || defined(KSH_ULIMIT2_TEST)
101*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_GFIL	1
102*7c356e86SAndroid Build Coastguard Worker #endif
103*7c356e86SAndroid Build Coastguard Worker 
104*7c356e86SAndroid Build Coastguard Worker #if defined(UL_SETFSIZE)
105*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_SFIL	UL_SETFSIZE
106*7c356e86SAndroid Build Coastguard Worker #elif defined(UL_SFILLIM)
107*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_SFIL	UL_SFILLIM
108*7c356e86SAndroid Build Coastguard Worker #elif defined(__A_UX__) || defined(KSH_ULIMIT2_TEST)
109*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_SFIL	2
110*7c356e86SAndroid Build Coastguard Worker #endif
111*7c356e86SAndroid Build Coastguard Worker 
112*7c356e86SAndroid Build Coastguard Worker #if defined(KSH_UL_SFIL)
113*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_WFIL	true
114*7c356e86SAndroid Build Coastguard Worker #else
115*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_WFIL	false
116*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_SFIL	0
117*7c356e86SAndroid Build Coastguard Worker #endif
118*7c356e86SAndroid Build Coastguard Worker 
119*7c356e86SAndroid Build Coastguard Worker #if defined(UL_GETMAXBRK)
120*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_GBRK	UL_GETMAXBRK
121*7c356e86SAndroid Build Coastguard Worker #elif defined(UL_GMEMLIM)
122*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_GBRK	UL_GMEMLIM
123*7c356e86SAndroid Build Coastguard Worker #elif defined(__A_UX__) || defined(KSH_ULIMIT2_TEST)
124*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_GBRK	3
125*7c356e86SAndroid Build Coastguard Worker #endif
126*7c356e86SAndroid Build Coastguard Worker 
127*7c356e86SAndroid Build Coastguard Worker #if defined(UL_GDESLIM)
128*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_GDES	UL_GDESLIM
129*7c356e86SAndroid Build Coastguard Worker #elif defined(__GLIBC__) || defined(KSH_ULIMIT2_TEST)
130*7c356e86SAndroid Build Coastguard Worker #define KSH_UL_GDES	4
131*7c356e86SAndroid Build Coastguard Worker #endif
132*7c356e86SAndroid Build Coastguard Worker 
133*7c356e86SAndroid Build Coastguard Worker extern char etext;
134*7c356e86SAndroid Build Coastguard Worker extern long ulimit(int, long);
135*7c356e86SAndroid Build Coastguard Worker 
136*7c356e86SAndroid Build Coastguard Worker #define LIMITS_GEN	"ulimits.gen"
137*7c356e86SAndroid Build Coastguard Worker 
138*7c356e86SAndroid Build Coastguard Worker #endif /* !HAVE_RLIMIT */
139*7c356e86SAndroid Build Coastguard Worker 
140*7c356e86SAndroid Build Coastguard Worker struct limits {
141*7c356e86SAndroid Build Coastguard Worker 	/* limit resource / read command */
142*7c356e86SAndroid Build Coastguard Worker 	int resource;
143*7c356e86SAndroid Build Coastguard Worker #if HAVE_RLIMIT
144*7c356e86SAndroid Build Coastguard Worker 	/* multiply by to get rlim_{cur,max} values */
145*7c356e86SAndroid Build Coastguard Worker 	unsigned int factor;
146*7c356e86SAndroid Build Coastguard Worker #else
147*7c356e86SAndroid Build Coastguard Worker 	/* write command */
148*7c356e86SAndroid Build Coastguard Worker 	int wesource;
149*7c356e86SAndroid Build Coastguard Worker 	/* writable? */
150*7c356e86SAndroid Build Coastguard Worker 	bool writable;
151*7c356e86SAndroid Build Coastguard Worker #endif
152*7c356e86SAndroid Build Coastguard Worker 	/* getopts char */
153*7c356e86SAndroid Build Coastguard Worker 	char optchar;
154*7c356e86SAndroid Build Coastguard Worker 	/* limit name */
155*7c356e86SAndroid Build Coastguard Worker 	char name[1];
156*7c356e86SAndroid Build Coastguard Worker };
157*7c356e86SAndroid Build Coastguard Worker 
158*7c356e86SAndroid Build Coastguard Worker #define RLIMITS_DEFNS
159*7c356e86SAndroid Build Coastguard Worker #if HAVE_RLIMIT
160*7c356e86SAndroid Build Coastguard Worker #define FN(lname,lid,lfac,lopt)				\
161*7c356e86SAndroid Build Coastguard Worker 	static const struct {				\
162*7c356e86SAndroid Build Coastguard Worker 		int resource;				\
163*7c356e86SAndroid Build Coastguard Worker 		unsigned int factor;			\
164*7c356e86SAndroid Build Coastguard Worker 		char optchar;				\
165*7c356e86SAndroid Build Coastguard Worker 		char name[sizeof(lname)];		\
166*7c356e86SAndroid Build Coastguard Worker 	} rlimits_ ## lid = {				\
167*7c356e86SAndroid Build Coastguard Worker 		lid, lfac, lopt, lname			\
168*7c356e86SAndroid Build Coastguard Worker 	};
169*7c356e86SAndroid Build Coastguard Worker #else
170*7c356e86SAndroid Build Coastguard Worker #define FN(lname,lg,ls,lw,lopt)				\
171*7c356e86SAndroid Build Coastguard Worker 	static const struct {				\
172*7c356e86SAndroid Build Coastguard Worker 		int rcmd;				\
173*7c356e86SAndroid Build Coastguard Worker 		int wcmd;				\
174*7c356e86SAndroid Build Coastguard Worker 		bool writable;				\
175*7c356e86SAndroid Build Coastguard Worker 		char optchar;				\
176*7c356e86SAndroid Build Coastguard Worker 		char name[sizeof(lname)];		\
177*7c356e86SAndroid Build Coastguard Worker 	} rlimits_ ## lg = {				\
178*7c356e86SAndroid Build Coastguard Worker 		lg, ls, lw, lopt, lname			\
179*7c356e86SAndroid Build Coastguard Worker 	};
180*7c356e86SAndroid Build Coastguard Worker #endif
181*7c356e86SAndroid Build Coastguard Worker #include LIMITS_GEN
182*7c356e86SAndroid Build Coastguard Worker 
183*7c356e86SAndroid Build Coastguard Worker static void print_ulimit(const struct limits *, int);
184*7c356e86SAndroid Build Coastguard Worker static int set_ulimit(const struct limits *, const char *, int);
185*7c356e86SAndroid Build Coastguard Worker 
186*7c356e86SAndroid Build Coastguard Worker static const struct limits * const rlimits[] = {
187*7c356e86SAndroid Build Coastguard Worker #define RLIMITS_ITEMS
188*7c356e86SAndroid Build Coastguard Worker #include LIMITS_GEN
189*7c356e86SAndroid Build Coastguard Worker };
190*7c356e86SAndroid Build Coastguard Worker 
191*7c356e86SAndroid Build Coastguard Worker static const char rlimits_opts[] =
192*7c356e86SAndroid Build Coastguard Worker #define RLIMITS_OPTCS
193*7c356e86SAndroid Build Coastguard Worker #include LIMITS_GEN
194*7c356e86SAndroid Build Coastguard Worker #ifndef RLIMIT_CORE
195*7c356e86SAndroid Build Coastguard Worker 	"c"
196*7c356e86SAndroid Build Coastguard Worker #endif
197*7c356e86SAndroid Build Coastguard Worker     ;
198*7c356e86SAndroid Build Coastguard Worker 
199*7c356e86SAndroid Build Coastguard Worker int
c_ulimit(const char ** wp)200*7c356e86SAndroid Build Coastguard Worker c_ulimit(const char **wp)
201*7c356e86SAndroid Build Coastguard Worker {
202*7c356e86SAndroid Build Coastguard Worker 	size_t i = 0;
203*7c356e86SAndroid Build Coastguard Worker 	int how = SOFT | HARD, optc;
204*7c356e86SAndroid Build Coastguard Worker 	char what = 'f';
205*7c356e86SAndroid Build Coastguard Worker 	bool all = false;
206*7c356e86SAndroid Build Coastguard Worker 
207*7c356e86SAndroid Build Coastguard Worker 	while ((optc = ksh_getopt(wp, &builtin_opt, rlimits_opts)) != -1)
208*7c356e86SAndroid Build Coastguard Worker 		switch (optc) {
209*7c356e86SAndroid Build Coastguard Worker 		case ORD('H'):
210*7c356e86SAndroid Build Coastguard Worker 			how = HARD;
211*7c356e86SAndroid Build Coastguard Worker 			break;
212*7c356e86SAndroid Build Coastguard Worker 		case ORD('S'):
213*7c356e86SAndroid Build Coastguard Worker 			how = SOFT;
214*7c356e86SAndroid Build Coastguard Worker 			break;
215*7c356e86SAndroid Build Coastguard Worker 		case ORD('a'):
216*7c356e86SAndroid Build Coastguard Worker 			all = true;
217*7c356e86SAndroid Build Coastguard Worker 			break;
218*7c356e86SAndroid Build Coastguard Worker 		case ORD('?'):
219*7c356e86SAndroid Build Coastguard Worker 			bi_errorf("usage: ulimit [-%s] [value]", rlimits_opts);
220*7c356e86SAndroid Build Coastguard Worker 			return (1);
221*7c356e86SAndroid Build Coastguard Worker 		default:
222*7c356e86SAndroid Build Coastguard Worker 			what = optc;
223*7c356e86SAndroid Build Coastguard Worker 		}
224*7c356e86SAndroid Build Coastguard Worker 
225*7c356e86SAndroid Build Coastguard Worker 	while (i < NELEM(rlimits)) {
226*7c356e86SAndroid Build Coastguard Worker 		if (rlimits[i]->optchar == what)
227*7c356e86SAndroid Build Coastguard Worker 			goto found;
228*7c356e86SAndroid Build Coastguard Worker 		++i;
229*7c356e86SAndroid Build Coastguard Worker 	}
230*7c356e86SAndroid Build Coastguard Worker #ifndef RLIMIT_CORE
231*7c356e86SAndroid Build Coastguard Worker 	if (what == ORD('c'))
232*7c356e86SAndroid Build Coastguard Worker 		/* silently accept */
233*7c356e86SAndroid Build Coastguard Worker 		return 0;
234*7c356e86SAndroid Build Coastguard Worker #endif
235*7c356e86SAndroid Build Coastguard Worker 	internal_warningf("ulimit: %c", what);
236*7c356e86SAndroid Build Coastguard Worker 	return (1);
237*7c356e86SAndroid Build Coastguard Worker  found:
238*7c356e86SAndroid Build Coastguard Worker 	if (wp[builtin_opt.optind]) {
239*7c356e86SAndroid Build Coastguard Worker 		if (all || wp[builtin_opt.optind + 1]) {
240*7c356e86SAndroid Build Coastguard Worker 			bi_errorf(Ttoo_many_args);
241*7c356e86SAndroid Build Coastguard Worker 			return (1);
242*7c356e86SAndroid Build Coastguard Worker 		}
243*7c356e86SAndroid Build Coastguard Worker 		return (set_ulimit(rlimits[i], wp[builtin_opt.optind], how));
244*7c356e86SAndroid Build Coastguard Worker 	}
245*7c356e86SAndroid Build Coastguard Worker 	if (!all)
246*7c356e86SAndroid Build Coastguard Worker 		print_ulimit(rlimits[i], how);
247*7c356e86SAndroid Build Coastguard Worker 	else for (i = 0; i < NELEM(rlimits); ++i) {
248*7c356e86SAndroid Build Coastguard Worker 		shprintf("-%c: %-20s  ", rlimits[i]->optchar, rlimits[i]->name);
249*7c356e86SAndroid Build Coastguard Worker 		print_ulimit(rlimits[i], how);
250*7c356e86SAndroid Build Coastguard Worker 	}
251*7c356e86SAndroid Build Coastguard Worker 	return (0);
252*7c356e86SAndroid Build Coastguard Worker }
253*7c356e86SAndroid Build Coastguard Worker 
254*7c356e86SAndroid Build Coastguard Worker #if HAVE_RLIMIT
255*7c356e86SAndroid Build Coastguard Worker #define RL_T rlim_t
256*7c356e86SAndroid Build Coastguard Worker #define RL_U (rlim_t)RLIM_INFINITY
257*7c356e86SAndroid Build Coastguard Worker #else
258*7c356e86SAndroid Build Coastguard Worker #define RL_T long
259*7c356e86SAndroid Build Coastguard Worker #define RL_U LONG_MAX
260*7c356e86SAndroid Build Coastguard Worker #endif
261*7c356e86SAndroid Build Coastguard Worker 
262*7c356e86SAndroid Build Coastguard Worker static int
set_ulimit(const struct limits * l,const char * v,int how MKSH_A_UNUSED)263*7c356e86SAndroid Build Coastguard Worker set_ulimit(const struct limits *l, const char *v, int how MKSH_A_UNUSED)
264*7c356e86SAndroid Build Coastguard Worker {
265*7c356e86SAndroid Build Coastguard Worker 	RL_T val = (RL_T)0;
266*7c356e86SAndroid Build Coastguard Worker #if HAVE_RLIMIT
267*7c356e86SAndroid Build Coastguard Worker 	struct rlimit limit;
268*7c356e86SAndroid Build Coastguard Worker #endif
269*7c356e86SAndroid Build Coastguard Worker 
270*7c356e86SAndroid Build Coastguard Worker 	if (strcmp(v, "unlimited") == 0)
271*7c356e86SAndroid Build Coastguard Worker 		val = RL_U;
272*7c356e86SAndroid Build Coastguard Worker 	else {
273*7c356e86SAndroid Build Coastguard Worker 		mksh_uari_t rval;
274*7c356e86SAndroid Build Coastguard Worker 
275*7c356e86SAndroid Build Coastguard Worker 		if (!evaluate(v, (mksh_ari_t *)&rval, KSH_RETURN_ERROR, false))
276*7c356e86SAndroid Build Coastguard Worker 			return (1);
277*7c356e86SAndroid Build Coastguard Worker 		/*
278*7c356e86SAndroid Build Coastguard Worker 		 * Avoid problems caused by typos that evaluate misses due
279*7c356e86SAndroid Build Coastguard Worker 		 * to evaluating unset parameters to 0...
280*7c356e86SAndroid Build Coastguard Worker 		 * If this causes problems, will have to add parameter to
281*7c356e86SAndroid Build Coastguard Worker 		 * evaluate() to control if unset params are 0 or an error.
282*7c356e86SAndroid Build Coastguard Worker 		 */
283*7c356e86SAndroid Build Coastguard Worker 		if (!rval && !ctype(v[0], C_DIGIT)) {
284*7c356e86SAndroid Build Coastguard Worker 			bi_errorf("invalid %s limit: %s", l->name, v);
285*7c356e86SAndroid Build Coastguard Worker 			return (1);
286*7c356e86SAndroid Build Coastguard Worker 		}
287*7c356e86SAndroid Build Coastguard Worker #if HAVE_RLIMIT
288*7c356e86SAndroid Build Coastguard Worker 		val = (rlim_t)((rlim_t)rval * l->factor);
289*7c356e86SAndroid Build Coastguard Worker #else
290*7c356e86SAndroid Build Coastguard Worker 		val = (RL_T)rval;
291*7c356e86SAndroid Build Coastguard Worker #endif
292*7c356e86SAndroid Build Coastguard Worker 	}
293*7c356e86SAndroid Build Coastguard Worker 
294*7c356e86SAndroid Build Coastguard Worker #if HAVE_RLIMIT
295*7c356e86SAndroid Build Coastguard Worker 	if (getrlimit(l->resource, &limit) < 0) {
296*7c356e86SAndroid Build Coastguard Worker #ifndef MKSH_SMALL
297*7c356e86SAndroid Build Coastguard Worker 		bi_errorf("limit %s could not be read, contact the mksh developers: %s",
298*7c356e86SAndroid Build Coastguard Worker 		    l->name, cstrerror(errno));
299*7c356e86SAndroid Build Coastguard Worker #endif
300*7c356e86SAndroid Build Coastguard Worker 		/* some can't be read */
301*7c356e86SAndroid Build Coastguard Worker 		limit.rlim_cur = RLIM_INFINITY;
302*7c356e86SAndroid Build Coastguard Worker 		limit.rlim_max = RLIM_INFINITY;
303*7c356e86SAndroid Build Coastguard Worker 	}
304*7c356e86SAndroid Build Coastguard Worker 	if (how & SOFT)
305*7c356e86SAndroid Build Coastguard Worker 		limit.rlim_cur = val;
306*7c356e86SAndroid Build Coastguard Worker 	if (how & HARD)
307*7c356e86SAndroid Build Coastguard Worker 		limit.rlim_max = val;
308*7c356e86SAndroid Build Coastguard Worker 	if (!setrlimit(l->resource, &limit))
309*7c356e86SAndroid Build Coastguard Worker 		return (0);
310*7c356e86SAndroid Build Coastguard Worker #else
311*7c356e86SAndroid Build Coastguard Worker 	if (l->writable == false) {
312*7c356e86SAndroid Build Coastguard Worker 	    /* check.t:ulimit-2 fails if we return 1 and/or do:
313*7c356e86SAndroid Build Coastguard Worker 		bi_errorf(Tf_ro, l->name);
314*7c356e86SAndroid Build Coastguard Worker 	    */
315*7c356e86SAndroid Build Coastguard Worker 		return (0);
316*7c356e86SAndroid Build Coastguard Worker 	}
317*7c356e86SAndroid Build Coastguard Worker 	if (ulimit(l->wesource, val) != -1L)
318*7c356e86SAndroid Build Coastguard Worker 		return (0);
319*7c356e86SAndroid Build Coastguard Worker #endif
320*7c356e86SAndroid Build Coastguard Worker 	if (errno == EPERM)
321*7c356e86SAndroid Build Coastguard Worker 		bi_errorf("%s exceeds allowable %s limit", v, l->name);
322*7c356e86SAndroid Build Coastguard Worker 	else
323*7c356e86SAndroid Build Coastguard Worker 		bi_errorf("bad %s limit: %s", l->name, cstrerror(errno));
324*7c356e86SAndroid Build Coastguard Worker 	return (1);
325*7c356e86SAndroid Build Coastguard Worker }
326*7c356e86SAndroid Build Coastguard Worker 
327*7c356e86SAndroid Build Coastguard Worker static void
print_ulimit(const struct limits * l,int how MKSH_A_UNUSED)328*7c356e86SAndroid Build Coastguard Worker print_ulimit(const struct limits *l, int how MKSH_A_UNUSED)
329*7c356e86SAndroid Build Coastguard Worker {
330*7c356e86SAndroid Build Coastguard Worker 	RL_T val = (RL_T)0;
331*7c356e86SAndroid Build Coastguard Worker #if HAVE_RLIMIT
332*7c356e86SAndroid Build Coastguard Worker 	struct rlimit limit;
333*7c356e86SAndroid Build Coastguard Worker 
334*7c356e86SAndroid Build Coastguard Worker 	if (getrlimit(l->resource, &limit))
335*7c356e86SAndroid Build Coastguard Worker #else
336*7c356e86SAndroid Build Coastguard Worker 	if ((val = ulimit(l->resource, 0)) < 0)
337*7c356e86SAndroid Build Coastguard Worker #endif
338*7c356e86SAndroid Build Coastguard Worker 	    {
339*7c356e86SAndroid Build Coastguard Worker 		shf_puts("unknown\n", shl_stdout);
340*7c356e86SAndroid Build Coastguard Worker 		return;
341*7c356e86SAndroid Build Coastguard Worker 	}
342*7c356e86SAndroid Build Coastguard Worker #if HAVE_RLIMIT
343*7c356e86SAndroid Build Coastguard Worker 	if (how & SOFT)
344*7c356e86SAndroid Build Coastguard Worker 		val = limit.rlim_cur;
345*7c356e86SAndroid Build Coastguard Worker 	else if (how & HARD)
346*7c356e86SAndroid Build Coastguard Worker 		val = limit.rlim_max;
347*7c356e86SAndroid Build Coastguard Worker #endif
348*7c356e86SAndroid Build Coastguard Worker 	if (val == RL_U)
349*7c356e86SAndroid Build Coastguard Worker 		shf_puts("unlimited\n", shl_stdout);
350*7c356e86SAndroid Build Coastguard Worker 	else {
351*7c356e86SAndroid Build Coastguard Worker #if HAVE_RLIMIT
352*7c356e86SAndroid Build Coastguard Worker 		val /= l->factor;
353*7c356e86SAndroid Build Coastguard Worker #elif defined(KSH_UL_GBRK)
354*7c356e86SAndroid Build Coastguard Worker 		if (l->resource == KSH_UL_GBRK)
355*7c356e86SAndroid Build Coastguard Worker 			val = (RL_T)(((size_t)val - (size_t)&etext) /
356*7c356e86SAndroid Build Coastguard Worker 			    (size_t)1024);
357*7c356e86SAndroid Build Coastguard Worker #endif
358*7c356e86SAndroid Build Coastguard Worker 		shprintf("%lu\n", (unsigned long)val);
359*7c356e86SAndroid Build Coastguard Worker 	}
360*7c356e86SAndroid Build Coastguard Worker }
361