xref: /netbsd-src/usr.bin/renice/renice.c (revision e2f11738e521c21ecf1e9ca32c6e71e1af017242)
1*e2f11738Swiz /*	$NetBSD: renice.c,v 1.20 2020/10/23 16:16:10 wiz Exp $	*/
25445d018Stls 
361f28255Scgd /*
45445d018Stls  * Copyright (c) 1983, 1989, 1993
55445d018Stls  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * Redistribution and use in source and binary forms, with or without
861f28255Scgd  * modification, are permitted provided that the following conditions
961f28255Scgd  * are met:
1061f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1261f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1461f28255Scgd  *    documentation and/or other materials provided with the distribution.
1589aaa1bbSagc  * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd  *    may be used to endorse or promote products derived from this software
1761f28255Scgd  *    without specific prior written permission.
1861f28255Scgd  *
1961f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd  * SUCH DAMAGE.
3061f28255Scgd  */
3161f28255Scgd 
323859d5b3Slukem #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
3498e5374cSlukem __COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1993\
3598e5374cSlukem  The Regents of the University of California.  All rights reserved.");
3661f28255Scgd #endif /* not lint */
3761f28255Scgd 
3861f28255Scgd #ifndef lint
395445d018Stls /*static char sccsid[] = "from: @(#)renice.c	8.1 (Berkeley) 6/9/93";*/
40*e2f11738Swiz __RCSID("$NetBSD: renice.c,v 1.20 2020/10/23 16:16:10 wiz Exp $");
4161f28255Scgd #endif /* not lint */
4261f28255Scgd 
4361f28255Scgd #include <sys/resource.h>
445445d018Stls 
453859d5b3Slukem #include <err.h>
46134164f4Ssimonb #include <errno.h>
47134164f4Ssimonb #include <limits.h>
4861f28255Scgd #include <pwd.h>
493859d5b3Slukem #include <stdio.h>
503859d5b3Slukem #include <stdlib.h>
51fcd0fb11Smatt #include <string.h>
52fbec9f21Schristos #include <sysexits.h>
533859d5b3Slukem 
54134164f4Ssimonb static int	getnum(const char *, const char *, int *);
55fbec9f21Schristos static int	donice(int, id_t, int, int);
568b0f9554Sperry static void	usage(void) __dead;
579126a73fSchristos 
5861f28255Scgd /*
5961f28255Scgd  * Change the priority (nice) of processes
6061f28255Scgd  * or groups of processes which are already
6161f28255Scgd  * running.
6261f28255Scgd  */
633859d5b3Slukem int
main(int argc,char ** argv)64134164f4Ssimonb main(int argc, char **argv)
6561f28255Scgd {
6661f28255Scgd 	int which = PRIO_PROCESS;
67fbec9f21Schristos 	int prio, errs = 0, incr = 0;
68fbec9f21Schristos 	id_t who = 0;
6961f28255Scgd 
7061f28255Scgd 	argc--, argv++;
719126a73fSchristos 	if (argc < 2)
729126a73fSchristos 		usage();
739126a73fSchristos 	if (strcmp(*argv, "-n") == 0) {
749126a73fSchristos 		incr = 1;
7561f28255Scgd 		argc--, argv++;
769c50e0e0Sdholland 		if (argc < 2)
779126a73fSchristos 			usage();
789126a73fSchristos 	}
799126a73fSchristos 	if (getnum("priority", *argv, &prio))
809126a73fSchristos 		return 1;
819126a73fSchristos 	argc--, argv++;
8261f28255Scgd 	for (; argc > 0; argc--, argv++) {
8361f28255Scgd 		if (strcmp(*argv, "-g") == 0) {
8461f28255Scgd 			which = PRIO_PGRP;
8561f28255Scgd 			continue;
8661f28255Scgd 		}
8761f28255Scgd 		if (strcmp(*argv, "-u") == 0) {
8861f28255Scgd 			which = PRIO_USER;
8961f28255Scgd 			continue;
9061f28255Scgd 		}
9161f28255Scgd 		if (strcmp(*argv, "-p") == 0) {
9261f28255Scgd 			which = PRIO_PROCESS;
9361f28255Scgd 			continue;
9461f28255Scgd 		}
9561f28255Scgd 		if (which == PRIO_USER) {
969126a73fSchristos 			struct passwd *pwd = getpwnam(*argv);
9761f28255Scgd 
9861f28255Scgd 			if (pwd == NULL) {
993859d5b3Slukem 				warnx("%s: unknown user", *argv);
100fbec9f21Schristos 				errs++;
10161f28255Scgd 				continue;
10261f28255Scgd 			}
103fbec9f21Schristos 			who = (id_t)pwd->pw_uid;
10461f28255Scgd 		} else {
105fbec9f21Schristos 			int twho;
106fbec9f21Schristos 			if (getnum("pid", *argv, &twho)) {
107fbec9f21Schristos 				errs++;
10861f28255Scgd 				continue;
10961f28255Scgd 			}
110fbec9f21Schristos 			if (twho < 0) {
111fbec9f21Schristos 				warnx("%s: bad value", *argv);
112fbec9f21Schristos 				errs++;
113fbec9f21Schristos 				continue;
114fbec9f21Schristos 			}
115fbec9f21Schristos 			who = (id_t)twho;
11661f28255Scgd 		}
1179126a73fSchristos 		errs += donice(which, who, prio, incr);
11861f28255Scgd 	}
119fbec9f21Schristos 	return errs == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
12061f28255Scgd }
12161f28255Scgd 
1229126a73fSchristos static int
getnum(const char * com,const char * str,int * val)123134164f4Ssimonb getnum(const char *com, const char *str, int *val)
1249126a73fSchristos {
1259126a73fSchristos 	long v;
1269126a73fSchristos 	char *ep;
1279126a73fSchristos 
128ef83aa34Slukem 	errno = 0;
1290933c426Sfvdl 	v = strtol(str, &ep, 0);
1309126a73fSchristos 
1319126a73fSchristos 	if (*ep) {
1329126a73fSchristos 		warnx("Bad %s argument: %s", com, str);
1339126a73fSchristos 		return 1;
1349126a73fSchristos 	}
1359126a73fSchristos 	if ((v == LONG_MIN || v == LONG_MAX) && errno == ERANGE) {
1369126a73fSchristos 		warn("Invalid %s argument: %s", com, str);
1379126a73fSchristos 		return 1;
1389126a73fSchristos 	}
1399126a73fSchristos 
1409126a73fSchristos 	*val = (int)v;
1419126a73fSchristos 	return 0;
1429126a73fSchristos }
1439126a73fSchristos 
1449126a73fSchristos static int
donice(int which,id_t who,int prio,int incr)145fbec9f21Schristos donice(int which, id_t who, int prio, int incr)
14661f28255Scgd {
14761f28255Scgd 	int oldprio;
14861f28255Scgd 
149bef45d1bSkleink 	errno = 0;
150bef45d1bSkleink 	if ((oldprio = getpriority(which, who)) == -1 && errno != 0) {
1513859d5b3Slukem 		warn("%d: getpriority", who);
152fbec9f21Schristos 		return 1;
15361f28255Scgd 	}
1549126a73fSchristos 
1559126a73fSchristos 	if (incr)
1569126a73fSchristos 		prio = oldprio + prio;
1579126a73fSchristos 
1589126a73fSchristos 	if (prio > PRIO_MAX)
1599126a73fSchristos 		prio = PRIO_MAX;
1609126a73fSchristos 	if (prio < PRIO_MIN)
1619126a73fSchristos 		prio = PRIO_MIN;
1629126a73fSchristos 
1639126a73fSchristos 	if (setpriority(which, who, prio) == -1) {
1643859d5b3Slukem 		warn("%d: setpriority", who);
165fbec9f21Schristos 		return 1;
16661f28255Scgd 	}
167fbec9f21Schristos 	(void)printf("%d: old priority %d, new priority %d\n",
168fbec9f21Schristos 	    who, oldprio, prio);
169fbec9f21Schristos 	return 0;
17061f28255Scgd }
1719126a73fSchristos 
1729126a73fSchristos static void
usage(void)173134164f4Ssimonb usage(void)
1749126a73fSchristos {
1759126a73fSchristos 
176fbec9f21Schristos 	(void)fprintf(stderr, "Usage: %s [<priority> | -n <incr>] ",
177fbec9f21Schristos 	    getprogname());
178*e2f11738Swiz 	(void)fprintf(stderr, "[[-gpu] who ...] ...\n");
1799126a73fSchristos 	exit(1);
1809126a73fSchristos }
181