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