renice.c revision 96761
1226026Sdelphij/*
2226026Sdelphij * Copyright (c) 1983, 1989, 1993
3226026Sdelphij *	The Regents of the University of California.  All rights reserved.
4226026Sdelphij *
5226026Sdelphij * Redistribution and use in source and binary forms, with or without
6226026Sdelphij * modification, are permitted provided that the following conditions
7226026Sdelphij * are met:
8226026Sdelphij * 1. Redistributions of source code must retain the above copyright
9226026Sdelphij *    notice, this list of conditions and the following disclaimer.
10226026Sdelphij * 2. Redistributions in binary form must reproduce the above copyright
11226026Sdelphij *    notice, this list of conditions and the following disclaimer in the
12226026Sdelphij *    documentation and/or other materials provided with the distribution.
13226026Sdelphij * 3. All advertising materials mentioning features or use of this software
14226026Sdelphij *    must display the following acknowledgement:
15226026Sdelphij *	This product includes software developed by the University of
16226026Sdelphij *	California, Berkeley and its contributors.
17226026Sdelphij * 4. Neither the name of the University nor the names of its contributors
18226026Sdelphij *    may be used to endorse or promote products derived from this software
19226026Sdelphij *    without specific prior written permission.
20226026Sdelphij *
21226026Sdelphij * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22226026Sdelphij * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23226026Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24226026Sdelphij * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25226026Sdelphij * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26226026Sdelphij * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27226026Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28226026Sdelphij * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29226026Sdelphij * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30226026Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31226026Sdelphij * SUCH DAMAGE.
32226026Sdelphij */
33226026Sdelphij
34226026Sdelphij#ifndef lint
35226026Sdelphijstatic const char copyright[] =
36226026Sdelphij"@(#) Copyright (c) 1983, 1989, 1993\n\
37226026Sdelphij	The Regents of the University of California.  All rights reserved.\n";
38226026Sdelphij#endif /* not lint */
39226026Sdelphij
40226026Sdelphij#ifndef lint
41226026Sdelphij#if 0
42226026Sdelphijstatic char sccsid[] = "@(#)renice.c	8.1 (Berkeley) 6/9/93";
43226026Sdelphij#endif
44276715Sjhbstatic const char rcsid[] =
45226026Sdelphij  "$FreeBSD: head/usr.bin/renice/renice.c 96761 2002-05-16 23:30:38Z tjr $";
46226026Sdelphij#endif /* not lint */
47226026Sdelphij
48226026Sdelphij#include <sys/types.h>
49226026Sdelphij#include <sys/time.h>
50226026Sdelphij#include <sys/resource.h>
51226026Sdelphij
52226026Sdelphij#include <err.h>
53226026Sdelphij#include <errno.h>
54226026Sdelphij#include <limits.h>
55226026Sdelphij#include <pwd.h>
56226026Sdelphij#include <stdio.h>
57226026Sdelphij#include <stdlib.h>
58226026Sdelphij#include <string.h>
59226026Sdelphij
60226026Sdelphijstatic int	donice(int, int, int, int);
61226026Sdelphijstatic int	getnum(const char *, const char *, int *);
62226026Sdelphijstatic void	usage(void);
63276715Sjhb
64226026Sdelphij/*
65226026Sdelphij * Change the priority (nice) of processes
66226026Sdelphij * or groups of processes which are already
67226026Sdelphij * running.
68226026Sdelphij */
69226026Sdelphijint
70226026Sdelphijmain(int argc, char *argv[])
71226026Sdelphij{
72226026Sdelphij	struct passwd *pwd;
73226026Sdelphij	int errs, incr, prio, which, who;
74226026Sdelphij
75226026Sdelphij	errs = 0;
76226026Sdelphij	incr = 0;
77226026Sdelphij	which = PRIO_PROCESS;
78226026Sdelphij	who = 0;
79226026Sdelphij	argc--, argv++;
80226026Sdelphij	if (argc < 2)
81226026Sdelphij		usage();
82226026Sdelphij	if (strcmp(*argv, "-n") == 0) {
83226026Sdelphij		incr = 1;
84226026Sdelphij		argc--, argv++;
85226026Sdelphij		if (argc < 2)
86226026Sdelphij			usage();
87226026Sdelphij	}
88226026Sdelphij	if (getnum("priority", *argv, &prio))
89226026Sdelphij		return (1);
90226026Sdelphij	argc--, argv++;
91226026Sdelphij	for (; argc > 0; argc--, argv++) {
92226026Sdelphij		if (strcmp(*argv, "-g") == 0) {
93226026Sdelphij			which = PRIO_PGRP;
94226026Sdelphij			continue;
95241753Sdelphij		}
96226026Sdelphij		if (strcmp(*argv, "-u") == 0) {
97226026Sdelphij			which = PRIO_USER;
98226026Sdelphij			continue;
99226026Sdelphij		}
100241753Sdelphij		if (strcmp(*argv, "-p") == 0) {
101241753Sdelphij			which = PRIO_PROCESS;
102241753Sdelphij			continue;
103226026Sdelphij		}
104226026Sdelphij		if (which == PRIO_USER) {
105226026Sdelphij			pwd = getpwnam(*argv);
106262572Sdelphij			if (pwd == NULL) {
107226026Sdelphij				warnx("%s: unknown user", *argv);
108226026Sdelphij				continue;
109226026Sdelphij			}
110226026Sdelphij			who = pwd->pw_uid;
111241753Sdelphij		} else {
112241753Sdelphij			if (getnum("pid", *argv, &who))
113241753Sdelphij				continue;
114241753Sdelphij			if (who < 0) {
115226026Sdelphij				warnx("%s: bad value", *argv);
116226026Sdelphij				continue;
117241753Sdelphij			}
118226026Sdelphij		}
119241753Sdelphij		errs += donice(which, who, prio, incr);
120226026Sdelphij	}
121226026Sdelphij	exit(errs != 0);
122241753Sdelphij}
123241753Sdelphij
124241753Sdelphijstatic int
125241753Sdelphijdonice(int which, int who, int prio, int incr)
126241753Sdelphij{
127241753Sdelphij	int oldprio;
128226026Sdelphij
129226026Sdelphij	errno = 0;
130241753Sdelphij	oldprio = getpriority(which, who);
131241753Sdelphij	if (oldprio == -1 && errno) {
132241753Sdelphij		warn("%d: getpriority", who);
133241753Sdelphij		return (1);
134226026Sdelphij	}
135226026Sdelphij	if (incr)
136226026Sdelphij		prio = oldprio + prio;
137226026Sdelphij	if (prio > PRIO_MAX)
138226026Sdelphij		prio = PRIO_MAX;
139226026Sdelphij	if (prio < PRIO_MIN)
140226026Sdelphij		prio = PRIO_MIN;
141226026Sdelphij	if (setpriority(which, who, prio) < 0) {
142226026Sdelphij		warn("%d: setpriority", who);
143226026Sdelphij		return (1);
144226026Sdelphij	}
145226026Sdelphij	fprintf(stderr, "%d: old priority %d, new priority %d\n", who,
146226026Sdelphij	    oldprio, prio);
147226026Sdelphij	return (0);
148241753Sdelphij}
149241753Sdelphij
150241753Sdelphijstatic int
151226026Sdelphijgetnum(const char *com, const char *str, int *val)
152226026Sdelphij{
153226026Sdelphij	long v;
154241753Sdelphij	char *ep;
155226026Sdelphij
156226026Sdelphij	errno = 0;
157241753Sdelphij	v = strtol(str, &ep, NULL);
158241753Sdelphij	if (v < INT_MIN || v > INT_MAX || errno == ERANGE) {
159241753Sdelphij		warnx("%s argument %s is out of range.", com, str);
160241753Sdelphij		return (1);
161241753Sdelphij	}
162226026Sdelphij	if (ep == str || *ep != '\0' || errno != 0) {
163226026Sdelphij		warnx("Bad %s argument: %s.", com, str);
164226026Sdelphij		return (1);
165226026Sdelphij	}
166226026Sdelphij
167226026Sdelphij	*val = (int)v;
168226026Sdelphij	return (0);
169226026Sdelphij}
170241753Sdelphij
171226026Sdelphijstatic void
172226026Sdelphijusage()
173226026Sdelphij{
174226026Sdelphij	fprintf(stderr, "%s\n%s\n",
175226026Sdelphij"usage: renice [priority | [-n incr]] [ [ -p ] pids ] [ [ -g ] pgrps ]",
176226026Sdelphij"              [ [ -u ] users ]");
177226026Sdelphij	exit(1);
178226026Sdelphij}
179241753Sdelphij