xref: /freebsd/bin/sh/miscbltin.c (revision 7a2afe644c45728b93a82e743e3bd49df17c3f43)
14b88c807SRodney W. Grimes /*-
24b88c807SRodney W. Grimes  * Copyright (c) 1991, 1993
34b88c807SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
44b88c807SRodney W. Grimes  *
54b88c807SRodney W. Grimes  * This code is derived from software contributed to Berkeley by
64b88c807SRodney W. Grimes  * Kenneth Almquist.
77a2afe64SJoerg Wunsch  * The ulimit() builtin has been contributed by Joerg Wunsch.
84b88c807SRodney W. Grimes  *
94b88c807SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
104b88c807SRodney W. Grimes  * modification, are permitted provided that the following conditions
114b88c807SRodney W. Grimes  * are met:
124b88c807SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
134b88c807SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
144b88c807SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
154b88c807SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
164b88c807SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
174b88c807SRodney W. Grimes  * 3. All advertising materials mentioning features or use of this software
184b88c807SRodney W. Grimes  *    must display the following acknowledgement:
194b88c807SRodney W. Grimes  *	This product includes software developed by the University of
204b88c807SRodney W. Grimes  *	California, Berkeley and its contributors.
214b88c807SRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
224b88c807SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
234b88c807SRodney W. Grimes  *    without specific prior written permission.
244b88c807SRodney W. Grimes  *
254b88c807SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
264b88c807SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
274b88c807SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
284b88c807SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
294b88c807SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
304b88c807SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
314b88c807SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
324b88c807SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
334b88c807SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
344b88c807SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
354b88c807SRodney W. Grimes  * SUCH DAMAGE.
3689730b29SDavid Greenman  *
377a2afe64SJoerg Wunsch  *	$Id: miscbltin.c,v 1.2 1994/09/24 02:57:52 davidg Exp $
384b88c807SRodney W. Grimes  */
394b88c807SRodney W. Grimes 
404b88c807SRodney W. Grimes #ifndef lint
414b88c807SRodney W. Grimes static char sccsid[] = "@(#)miscbltin.c	8.2 (Berkeley) 4/16/94";
424b88c807SRodney W. Grimes #endif /* not lint */
434b88c807SRodney W. Grimes 
444b88c807SRodney W. Grimes /*
454b88c807SRodney W. Grimes  * Miscelaneous builtins.
464b88c807SRodney W. Grimes  */
474b88c807SRodney W. Grimes 
484b88c807SRodney W. Grimes #include "shell.h"
494b88c807SRodney W. Grimes #include "options.h"
504b88c807SRodney W. Grimes #include "var.h"
514b88c807SRodney W. Grimes #include "output.h"
524b88c807SRodney W. Grimes #include "memalloc.h"
534b88c807SRodney W. Grimes #include "error.h"
544b88c807SRodney W. Grimes #include "mystring.h"
554b88c807SRodney W. Grimes 
567a2afe64SJoerg Wunsch #include <stdio.h>
577a2afe64SJoerg Wunsch #include <stdlib.h>
587a2afe64SJoerg Wunsch #include <string.h>
597a2afe64SJoerg Wunsch #include <errno.h>
607a2afe64SJoerg Wunsch 
617a2afe64SJoerg Wunsch #if BSD
627a2afe64SJoerg Wunsch #include <limits.h>
637a2afe64SJoerg Wunsch #include <sys/types.h>
647a2afe64SJoerg Wunsch #include <sys/time.h>
657a2afe64SJoerg Wunsch #include <sys/resource.h>
667a2afe64SJoerg Wunsch #endif
677a2afe64SJoerg Wunsch 
684b88c807SRodney W. Grimes #undef eflag
694b88c807SRodney W. Grimes 
704b88c807SRodney W. Grimes extern char **argptr;		/* argument list for builtin command */
714b88c807SRodney W. Grimes 
724b88c807SRodney W. Grimes 
734b88c807SRodney W. Grimes /*
744b88c807SRodney W. Grimes  * The read builtin.  The -e option causes backslashes to escape the
754b88c807SRodney W. Grimes  * following character.
764b88c807SRodney W. Grimes  *
774b88c807SRodney W. Grimes  * This uses unbuffered input, which may be avoidable in some cases.
784b88c807SRodney W. Grimes  */
794b88c807SRodney W. Grimes 
804b88c807SRodney W. Grimes readcmd(argc, argv)  char **argv; {
814b88c807SRodney W. Grimes 	char **ap;
824b88c807SRodney W. Grimes 	int backslash;
834b88c807SRodney W. Grimes 	char c;
844b88c807SRodney W. Grimes 	int eflag;
854b88c807SRodney W. Grimes 	char *prompt;
864b88c807SRodney W. Grimes 	char *ifs;
874b88c807SRodney W. Grimes 	char *p;
884b88c807SRodney W. Grimes 	int startword;
894b88c807SRodney W. Grimes 	int status;
904b88c807SRodney W. Grimes 	int i;
914b88c807SRodney W. Grimes 
924b88c807SRodney W. Grimes 	eflag = 0;
934b88c807SRodney W. Grimes 	prompt = NULL;
944b88c807SRodney W. Grimes 	while ((i = nextopt("ep:")) != '\0') {
954b88c807SRodney W. Grimes 		if (i == 'p')
964b88c807SRodney W. Grimes 			prompt = optarg;
974b88c807SRodney W. Grimes 		else
984b88c807SRodney W. Grimes 			eflag = 1;
994b88c807SRodney W. Grimes 	}
1004b88c807SRodney W. Grimes 	if (prompt && isatty(0)) {
1014b88c807SRodney W. Grimes 		out2str(prompt);
1024b88c807SRodney W. Grimes 		flushall();
1034b88c807SRodney W. Grimes 	}
1044b88c807SRodney W. Grimes 	if (*(ap = argptr) == NULL)
1054b88c807SRodney W. Grimes 		error("arg count");
1064b88c807SRodney W. Grimes 	if ((ifs = bltinlookup("IFS", 1)) == NULL)
1074b88c807SRodney W. Grimes 		ifs = nullstr;
1084b88c807SRodney W. Grimes 	status = 0;
1094b88c807SRodney W. Grimes 	startword = 1;
1104b88c807SRodney W. Grimes 	backslash = 0;
1114b88c807SRodney W. Grimes 	STARTSTACKSTR(p);
1124b88c807SRodney W. Grimes 	for (;;) {
1134b88c807SRodney W. Grimes 		if (read(0, &c, 1) != 1) {
1144b88c807SRodney W. Grimes 			status = 1;
1154b88c807SRodney W. Grimes 			break;
1164b88c807SRodney W. Grimes 		}
1174b88c807SRodney W. Grimes 		if (c == '\0')
1184b88c807SRodney W. Grimes 			continue;
1194b88c807SRodney W. Grimes 		if (backslash) {
1204b88c807SRodney W. Grimes 			backslash = 0;
1214b88c807SRodney W. Grimes 			if (c != '\n')
1224b88c807SRodney W. Grimes 				STPUTC(c, p);
1234b88c807SRodney W. Grimes 			continue;
1244b88c807SRodney W. Grimes 		}
1254b88c807SRodney W. Grimes 		if (eflag && c == '\\') {
1264b88c807SRodney W. Grimes 			backslash++;
1274b88c807SRodney W. Grimes 			continue;
1284b88c807SRodney W. Grimes 		}
1294b88c807SRodney W. Grimes 		if (c == '\n')
1304b88c807SRodney W. Grimes 			break;
1314b88c807SRodney W. Grimes 		if (startword && *ifs == ' ' && strchr(ifs, c)) {
1324b88c807SRodney W. Grimes 			continue;
1334b88c807SRodney W. Grimes 		}
1344b88c807SRodney W. Grimes 		startword = 0;
1354b88c807SRodney W. Grimes 		if (backslash && c == '\\') {
1364b88c807SRodney W. Grimes 			if (read(0, &c, 1) != 1) {
1374b88c807SRodney W. Grimes 				status = 1;
1384b88c807SRodney W. Grimes 				break;
1394b88c807SRodney W. Grimes 			}
1404b88c807SRodney W. Grimes 			STPUTC(c, p);
1414b88c807SRodney W. Grimes 		} else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
1424b88c807SRodney W. Grimes 			STACKSTRNUL(p);
1434b88c807SRodney W. Grimes 			setvar(*ap, stackblock(), 0);
1444b88c807SRodney W. Grimes 			ap++;
1454b88c807SRodney W. Grimes 			startword = 1;
1464b88c807SRodney W. Grimes 			STARTSTACKSTR(p);
1474b88c807SRodney W. Grimes 		} else {
1484b88c807SRodney W. Grimes 			STPUTC(c, p);
1494b88c807SRodney W. Grimes 		}
1504b88c807SRodney W. Grimes 	}
1514b88c807SRodney W. Grimes 	STACKSTRNUL(p);
1524b88c807SRodney W. Grimes 	setvar(*ap, stackblock(), 0);
1534b88c807SRodney W. Grimes 	while (*++ap != NULL)
1544b88c807SRodney W. Grimes 		setvar(*ap, nullstr, 0);
1554b88c807SRodney W. Grimes 	return status;
1564b88c807SRodney W. Grimes }
1574b88c807SRodney W. Grimes 
1584b88c807SRodney W. Grimes 
1594b88c807SRodney W. Grimes 
1604b88c807SRodney W. Grimes umaskcmd(argc, argv)  char **argv; {
1614b88c807SRodney W. Grimes 	int mask;
1624b88c807SRodney W. Grimes 	char *p;
1634b88c807SRodney W. Grimes 	int i;
1644b88c807SRodney W. Grimes 
1654b88c807SRodney W. Grimes 	if ((p = argv[1]) == NULL) {
1664b88c807SRodney W. Grimes 		INTOFF;
1674b88c807SRodney W. Grimes 		mask = umask(0);
1684b88c807SRodney W. Grimes 		umask(mask);
1694b88c807SRodney W. Grimes 		INTON;
1704b88c807SRodney W. Grimes 		out1fmt("%.4o\n", mask);	/* %#o might be better */
1714b88c807SRodney W. Grimes 	} else {
1724b88c807SRodney W. Grimes 		mask = 0;
1734b88c807SRodney W. Grimes 		do {
1744b88c807SRodney W. Grimes 			if ((unsigned)(i = *p - '0') >= 8)
1754b88c807SRodney W. Grimes 				error("Illegal number: %s", argv[1]);
1764b88c807SRodney W. Grimes 			mask = (mask << 3) + i;
1774b88c807SRodney W. Grimes 		} while (*++p != '\0');
1784b88c807SRodney W. Grimes 		umask(mask);
1794b88c807SRodney W. Grimes 	}
1804b88c807SRodney W. Grimes 	return 0;
1814b88c807SRodney W. Grimes }
1827a2afe64SJoerg Wunsch 
1837a2afe64SJoerg Wunsch 
1847a2afe64SJoerg Wunsch #if BSD
1857a2afe64SJoerg Wunsch struct restab {
1867a2afe64SJoerg Wunsch 	int resource;
1877a2afe64SJoerg Wunsch 	int scale;
1887a2afe64SJoerg Wunsch 	char *descript;
1897a2afe64SJoerg Wunsch };
1907a2afe64SJoerg Wunsch 
1917a2afe64SJoerg Wunsch /* multi-purpose */
1927a2afe64SJoerg Wunsch #define RLIMIT_UNSPEC (-2)
1937a2afe64SJoerg Wunsch 
1947a2afe64SJoerg Wunsch /* resource */
1957a2afe64SJoerg Wunsch #define RLIMIT_ALL (-1)
1967a2afe64SJoerg Wunsch 
1977a2afe64SJoerg Wunsch /* mode */
1987a2afe64SJoerg Wunsch #define RLIMIT_SHOW 0
1997a2afe64SJoerg Wunsch #define RLIMIT_SET 1
2007a2afe64SJoerg Wunsch 
2017a2afe64SJoerg Wunsch /* what */
2027a2afe64SJoerg Wunsch #define RLIMIT_SOFT 1
2037a2afe64SJoerg Wunsch #define RLIMIT_HARD 2
2047a2afe64SJoerg Wunsch 
2057a2afe64SJoerg Wunsch static struct restab restab[] = {
2067a2afe64SJoerg Wunsch 	{RLIMIT_CORE,     512,  "coredump(512-blocks)    "},
2077a2afe64SJoerg Wunsch 	{RLIMIT_CPU,      1,    "time(seconds)           "},
2087a2afe64SJoerg Wunsch 	{RLIMIT_DATA,     1024, "datasize(kilobytes)     "},
2097a2afe64SJoerg Wunsch 	{RLIMIT_FSIZE,    512,  "filesize(512-blocks)    "},
2107a2afe64SJoerg Wunsch 	{RLIMIT_MEMLOCK,  1024, "lockedmem(kilobytes)    "},
2117a2afe64SJoerg Wunsch 	{RLIMIT_NOFILE,   1,    "nofiles(descriptors)    "},
2127a2afe64SJoerg Wunsch 	{RLIMIT_NPROC,    1,    "processes(max)          "},
2137a2afe64SJoerg Wunsch 	{RLIMIT_RSS,      1024, "memoryuse(kilobytes)    "},
2147a2afe64SJoerg Wunsch 	{RLIMIT_STACK,    1024, "stacksize(kilobytes)    "}
2157a2afe64SJoerg Wunsch };
2167a2afe64SJoerg Wunsch 
2177a2afe64SJoerg Wunsch /* get entry into above table */
2187a2afe64SJoerg Wunsch static struct restab *
2197a2afe64SJoerg Wunsch find_resource(resource) {
2207a2afe64SJoerg Wunsch 	int i;
2217a2afe64SJoerg Wunsch 	struct restab *rp;
2227a2afe64SJoerg Wunsch 
2237a2afe64SJoerg Wunsch 	for(i = 0, rp = restab;
2247a2afe64SJoerg Wunsch 	    i < sizeof restab / sizeof(struct restab);
2257a2afe64SJoerg Wunsch 	    i++, rp++)
2267a2afe64SJoerg Wunsch 		if(rp->resource == resource)
2277a2afe64SJoerg Wunsch 			return rp;
2287a2afe64SJoerg Wunsch 	error("internal error: resource not in table");
2297a2afe64SJoerg Wunsch 	return 0;
2307a2afe64SJoerg Wunsch }
2317a2afe64SJoerg Wunsch 
2327a2afe64SJoerg Wunsch static void
2337a2afe64SJoerg Wunsch print_resource(rp, what, with_descript) struct restab *rp; {
2347a2afe64SJoerg Wunsch 	struct rlimit rlim;
2357a2afe64SJoerg Wunsch 	quad_t val;
2367a2afe64SJoerg Wunsch 
2377a2afe64SJoerg Wunsch 	(void)getrlimit(rp->resource, &rlim);
2387a2afe64SJoerg Wunsch 	val = (what == RLIMIT_SOFT)?
2397a2afe64SJoerg Wunsch 		rlim.rlim_cur: rlim.rlim_max;
2407a2afe64SJoerg Wunsch 	if(with_descript)
2417a2afe64SJoerg Wunsch 		out1str(rp->descript);
2427a2afe64SJoerg Wunsch 	if(val == RLIM_INFINITY)
2437a2afe64SJoerg Wunsch 		out1str("unlimited\n");
2447a2afe64SJoerg Wunsch 	else {
2457a2afe64SJoerg Wunsch 		val /= (quad_t)rp->scale;
2467a2afe64SJoerg Wunsch 		if(val > (quad_t)ULONG_MAX)
2477a2afe64SJoerg Wunsch 			out1fmt("> %lu\n", (unsigned long)ULONG_MAX);
2487a2afe64SJoerg Wunsch 		else
2497a2afe64SJoerg Wunsch 			out1fmt("%lu\n", (unsigned long)val);
2507a2afe64SJoerg Wunsch 	}
2517a2afe64SJoerg Wunsch }
2527a2afe64SJoerg Wunsch 
2537a2afe64SJoerg Wunsch ulimitcmd(argc, argv)  char **argv; {
2547a2afe64SJoerg Wunsch 	struct rlimit rlim;
2557a2afe64SJoerg Wunsch 	char *p;
2567a2afe64SJoerg Wunsch 	int i;
2577a2afe64SJoerg Wunsch 	int resource = RLIMIT_UNSPEC;
2587a2afe64SJoerg Wunsch 	quad_t val;
2597a2afe64SJoerg Wunsch 	int what = RLIMIT_UNSPEC;
2607a2afe64SJoerg Wunsch 	int mode = RLIMIT_UNSPEC;
2617a2afe64SJoerg Wunsch 	int errs = 0, arg = 1;
2627a2afe64SJoerg Wunsch 	struct restab *rp;
2637a2afe64SJoerg Wunsch 	extern int optreset;	/* XXX should be declared in <stdlib.h> */
2647a2afe64SJoerg Wunsch 
2657a2afe64SJoerg Wunsch 	opterr = 0;		/* use own error processing */
2667a2afe64SJoerg Wunsch 	optreset = 1;
2677a2afe64SJoerg Wunsch 	optind = 1;
2687a2afe64SJoerg Wunsch 	while ((i = getopt(argc, argv, "HSacdfnstmlp")) != EOF) {
2697a2afe64SJoerg Wunsch 		arg++;
2707a2afe64SJoerg Wunsch 		switch(i) {
2717a2afe64SJoerg Wunsch 		case 'H':
2727a2afe64SJoerg Wunsch 			if(what == RLIMIT_UNSPEC) what = 0;
2737a2afe64SJoerg Wunsch 			what |= RLIMIT_HARD;
2747a2afe64SJoerg Wunsch 			break;
2757a2afe64SJoerg Wunsch 		case 'S':
2767a2afe64SJoerg Wunsch 			if(what == RLIMIT_UNSPEC) what = 0;
2777a2afe64SJoerg Wunsch 			what |= RLIMIT_SOFT;
2787a2afe64SJoerg Wunsch 			break;
2797a2afe64SJoerg Wunsch 		case 'a':
2807a2afe64SJoerg Wunsch 			if(resource != RLIMIT_UNSPEC) errs++;
2817a2afe64SJoerg Wunsch 			resource = RLIMIT_ALL;
2827a2afe64SJoerg Wunsch 			mode = RLIMIT_SHOW;
2837a2afe64SJoerg Wunsch 			break;
2847a2afe64SJoerg Wunsch 		case 'c':
2857a2afe64SJoerg Wunsch 			if(resource != RLIMIT_UNSPEC) errs++;
2867a2afe64SJoerg Wunsch 			resource = RLIMIT_CORE;
2877a2afe64SJoerg Wunsch 			break;
2887a2afe64SJoerg Wunsch 		case 'd':
2897a2afe64SJoerg Wunsch 			if(resource != RLIMIT_UNSPEC) errs++;
2907a2afe64SJoerg Wunsch 			resource = RLIMIT_DATA;
2917a2afe64SJoerg Wunsch 			break;
2927a2afe64SJoerg Wunsch 		case 'f':
2937a2afe64SJoerg Wunsch 			if(resource != RLIMIT_UNSPEC) errs++;
2947a2afe64SJoerg Wunsch 			resource = RLIMIT_FSIZE;
2957a2afe64SJoerg Wunsch 			break;
2967a2afe64SJoerg Wunsch 		case 'n':
2977a2afe64SJoerg Wunsch 			if(resource != RLIMIT_UNSPEC) errs++;
2987a2afe64SJoerg Wunsch 			resource = RLIMIT_NOFILE;
2997a2afe64SJoerg Wunsch 			break;
3007a2afe64SJoerg Wunsch 		case 's':
3017a2afe64SJoerg Wunsch 			if(resource != RLIMIT_UNSPEC) errs++;
3027a2afe64SJoerg Wunsch 			resource = RLIMIT_STACK;
3037a2afe64SJoerg Wunsch 			break;
3047a2afe64SJoerg Wunsch 		case 't':
3057a2afe64SJoerg Wunsch 			if(resource != RLIMIT_UNSPEC) errs++;
3067a2afe64SJoerg Wunsch 			resource = RLIMIT_CPU;
3077a2afe64SJoerg Wunsch 			break;
3087a2afe64SJoerg Wunsch 		case 'm':
3097a2afe64SJoerg Wunsch 			if(resource != RLIMIT_UNSPEC) errs++;
3107a2afe64SJoerg Wunsch 			resource = RLIMIT_RSS;
3117a2afe64SJoerg Wunsch 			break;
3127a2afe64SJoerg Wunsch 		case 'l':
3137a2afe64SJoerg Wunsch 			if(resource != RLIMIT_UNSPEC) errs++;
3147a2afe64SJoerg Wunsch 			resource = RLIMIT_MEMLOCK;
3157a2afe64SJoerg Wunsch 			break;
3167a2afe64SJoerg Wunsch 		case 'p':
3177a2afe64SJoerg Wunsch 			if(resource != RLIMIT_UNSPEC) errs++;
3187a2afe64SJoerg Wunsch 			resource = RLIMIT_NPROC;
3197a2afe64SJoerg Wunsch 			break;
3207a2afe64SJoerg Wunsch 		case '?':
3217a2afe64SJoerg Wunsch 			error("illegal option -%c", optopt);
3227a2afe64SJoerg Wunsch 		}
3237a2afe64SJoerg Wunsch 	}
3247a2afe64SJoerg Wunsch 
3257a2afe64SJoerg Wunsch 	argc -= optind;
3267a2afe64SJoerg Wunsch 	argv += optind;
3277a2afe64SJoerg Wunsch 	if(argc > 1)
3287a2afe64SJoerg Wunsch 		error("too many arguments");
3297a2afe64SJoerg Wunsch 	if(argc == 0)
3307a2afe64SJoerg Wunsch 		mode = RLIMIT_SHOW;
3317a2afe64SJoerg Wunsch 	else if (resource == RLIMIT_ALL)
3327a2afe64SJoerg Wunsch 		errs++;
3337a2afe64SJoerg Wunsch 	else
3347a2afe64SJoerg Wunsch 		mode = RLIMIT_SET;
3357a2afe64SJoerg Wunsch 	if(mode == RLIMIT_UNSPEC)
3367a2afe64SJoerg Wunsch 		mode = RLIMIT_SHOW;
3377a2afe64SJoerg Wunsch 	if(resource == RLIMIT_UNSPEC)
3387a2afe64SJoerg Wunsch 		resource = RLIMIT_FSIZE;
3397a2afe64SJoerg Wunsch 	if(what == RLIMIT_UNSPEC)
3407a2afe64SJoerg Wunsch 		what = (mode == RLIMIT_SHOW)?
3417a2afe64SJoerg Wunsch 			RLIMIT_SOFT: (RLIMIT_SOFT|RLIMIT_HARD);
3427a2afe64SJoerg Wunsch 	if(mode == RLIMIT_SHOW && what == (RLIMIT_SOFT|RLIMIT_HARD))
3437a2afe64SJoerg Wunsch 		errs++;
3447a2afe64SJoerg Wunsch 	if(errs)
3457a2afe64SJoerg Wunsch 		error("Wrong option combination");
3467a2afe64SJoerg Wunsch 
3477a2afe64SJoerg Wunsch 	if(resource == RLIMIT_ALL)
3487a2afe64SJoerg Wunsch 		for(i = 0; i < sizeof restab / sizeof(struct restab); i++)
3497a2afe64SJoerg Wunsch 			print_resource(restab + i, what, 1);
3507a2afe64SJoerg Wunsch 	else if(mode == RLIMIT_SHOW)
3517a2afe64SJoerg Wunsch 		print_resource(find_resource(resource), what, 0);
3527a2afe64SJoerg Wunsch 	else {
3537a2afe64SJoerg Wunsch 		rp = find_resource(resource);
3547a2afe64SJoerg Wunsch 		if(strcmp(argv[0], "unlimited") == 0)
3557a2afe64SJoerg Wunsch 			val = RLIM_INFINITY;
3567a2afe64SJoerg Wunsch 		else {
3577a2afe64SJoerg Wunsch 			val = 0;
3587a2afe64SJoerg Wunsch 			p = argv[0];
3597a2afe64SJoerg Wunsch 			do {
3607a2afe64SJoerg Wunsch 				if((i = *p - '0') < 0 || i > 9)
3617a2afe64SJoerg Wunsch 					error("Illegal number: %s", argv[0]);
3627a2afe64SJoerg Wunsch 				val = (10 * val) + (quad_t)i;
3637a2afe64SJoerg Wunsch 			} while (*++p != '\0');
3647a2afe64SJoerg Wunsch 			val *= (quad_t)rp->scale;
3657a2afe64SJoerg Wunsch 		}
3667a2afe64SJoerg Wunsch 		(void)getrlimit(resource, &rlim);
3677a2afe64SJoerg Wunsch 		if(what & RLIMIT_HARD)
3687a2afe64SJoerg Wunsch 			rlim.rlim_max = val;
3697a2afe64SJoerg Wunsch 		if(what & RLIMIT_SOFT)
3707a2afe64SJoerg Wunsch 			rlim.rlim_cur = val;
3717a2afe64SJoerg Wunsch 		if(setrlimit(resource, &rlim) == -1) {
3727a2afe64SJoerg Wunsch 			outfmt(&errout, "ulimit: bad limit: %s\n",
3737a2afe64SJoerg Wunsch 			       strerror(errno));
3747a2afe64SJoerg Wunsch 			return 1;
3757a2afe64SJoerg Wunsch 		}
3767a2afe64SJoerg Wunsch 	}
3777a2afe64SJoerg Wunsch 	return 0;
3787a2afe64SJoerg Wunsch }
3797a2afe64SJoerg Wunsch #else /* !BSD */
3807a2afe64SJoerg Wunsch #error ulimit() not implemented
3817a2afe64SJoerg Wunsch #endif /* BSD */
382