renice.c revision 216370
1112918Sjeff/*
2112918Sjeff * Copyright (c) 1983, 1989, 1993
3112918Sjeff *	The Regents of the University of California.  All rights reserved.
4112918Sjeff *
5112918Sjeff * Redistribution and use in source and binary forms, with or without
6112918Sjeff * modification, are permitted provided that the following conditions
7112918Sjeff * are met:
8112918Sjeff * 1. Redistributions of source code must retain the above copyright
9112918Sjeff *    notice, this list of conditions and the following disclaimer.
10112918Sjeff * 2. Redistributions in binary form must reproduce the above copyright
11112918Sjeff *    notice, this list of conditions and the following disclaimer in the
12112918Sjeff *    documentation and/or other materials provided with the distribution.
13112918Sjeff * 4. Neither the name of the University nor the names of its contributors
14112918Sjeff *    may be used to endorse or promote products derived from this software
15112918Sjeff *    without specific prior written permission.
16112918Sjeff *
17112918Sjeff * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18112918Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19112918Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20112918Sjeff * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21112918Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22112918Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23112918Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24112918Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25112918Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26112918Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27112918Sjeff * SUCH DAMAGE.
28112918Sjeff */
29112918Sjeff
30112918Sjeff#ifndef lint
31112918Sjeffstatic const char copyright[] =
32112918Sjeff"@(#) Copyright (c) 1983, 1989, 1993\n\
33112918Sjeff	The Regents of the University of California.  All rights reserved.\n";
34112918Sjeff#endif /* not lint */
35112918Sjeff
36112918Sjeff#if 0
37112918Sjeff#ifndef lint
38112918Sjeffstatic char sccsid[] = "@(#)renice.c	8.1 (Berkeley) 6/9/93";
39112918Sjeff#endif /* not lint */
40112918Sjeff#endif
41112918Sjeff
42112918Sjeff#include <sys/cdefs.h>
43112918Sjeff__FBSDID("$FreeBSD: head/usr.bin/renice/renice.c 216370 2010-12-11 08:32:16Z joel $");
44112918Sjeff
45112918Sjeff#include <sys/types.h>
46115035Smtm#include <sys/time.h>
47115035Smtm#include <sys/resource.h>
48112918Sjeff
49112918Sjeff#include <err.h>
50112918Sjeff#include <errno.h>
51112918Sjeff#include <limits.h>
52112918Sjeff#include <pwd.h>
53112918Sjeff#include <stdio.h>
54112918Sjeff#include <stdlib.h>
55112918Sjeff#include <string.h>
56112918Sjeff
57112918Sjeffstatic int	donice(int, int, int, int);
58112918Sjeffstatic int	getnum(const char *, const char *, int *);
59112918Sjeffstatic void	usage(void);
60112918Sjeff
61112918Sjeff/*
62112918Sjeff * Change the priority (nice) of processes
63112918Sjeff * or groups of processes which are already
64112918Sjeff * running.
65112918Sjeff */
66112918Sjeffint
67112918Sjeffmain(int argc, char *argv[])
68112918Sjeff{
69112918Sjeff	struct passwd *pwd;
70112918Sjeff	int errs, incr, prio, which, who;
71112918Sjeff
72112918Sjeff	errs = 0;
73112918Sjeff	incr = 0;
74112918Sjeff	which = PRIO_PROCESS;
75112918Sjeff	who = 0;
76112918Sjeff	argc--, argv++;
77112918Sjeff	if (argc < 2)
78112918Sjeff		usage();
79112918Sjeff	if (strcmp(*argv, "-n") == 0) {
80112918Sjeff		incr = 1;
81112918Sjeff		argc--, argv++;
82112918Sjeff		if (argc < 2)
83112918Sjeff			usage();
84112918Sjeff	}
85112918Sjeff	if (getnum("priority", *argv, &prio))
86112918Sjeff		return (1);
87112918Sjeff	argc--, argv++;
88112918Sjeff	for (; argc > 0; argc--, argv++) {
89112918Sjeff		if (strcmp(*argv, "-g") == 0) {
90112918Sjeff			which = PRIO_PGRP;
91112918Sjeff			continue;
92112918Sjeff		}
93112918Sjeff		if (strcmp(*argv, "-u") == 0) {
94112918Sjeff			which = PRIO_USER;
95112918Sjeff			continue;
96112918Sjeff		}
97112918Sjeff		if (strcmp(*argv, "-p") == 0) {
98112918Sjeff			which = PRIO_PROCESS;
99112918Sjeff			continue;
100112918Sjeff		}
101112918Sjeff		if (which == PRIO_USER) {
102112918Sjeff			if ((pwd = getpwnam(*argv)) != NULL)
103112918Sjeff				who = pwd->pw_uid;
104112918Sjeff			else if (getnum("uid", *argv, &who)) {
105112918Sjeff				errs++;
106112918Sjeff				continue;
107112918Sjeff			} else if (who < 0) {
108112918Sjeff				warnx("%s: bad value", *argv);
109112918Sjeff				errs++;
110112918Sjeff				continue;
111112918Sjeff			}
112112918Sjeff		} else {
113112918Sjeff			if (getnum("pid", *argv, &who)) {
114112918Sjeff				errs++;
115112918Sjeff				continue;
116112918Sjeff			}
117112918Sjeff			if (who < 0) {
118112918Sjeff				warnx("%s: bad value", *argv);
119112918Sjeff				errs++;
120112918Sjeff				continue;
121112918Sjeff			}
122112918Sjeff		}
123112918Sjeff		errs += donice(which, who, prio, incr);
124112918Sjeff	}
125112918Sjeff	exit(errs != 0);
126112918Sjeff}
127112918Sjeff
128112918Sjeffstatic int
129112918Sjeffdonice(int which, int who, int prio, int incr)
130112918Sjeff{
131112918Sjeff	int oldprio;
132112918Sjeff
133112918Sjeff	errno = 0;
134112918Sjeff	oldprio = getpriority(which, who);
135112918Sjeff	if (oldprio == -1 && errno) {
136112918Sjeff		warn("%d: getpriority", who);
137112918Sjeff		return (1);
138112918Sjeff	}
139112918Sjeff	if (incr)
140112918Sjeff		prio = oldprio + prio;
141112918Sjeff	if (prio > PRIO_MAX)
142112918Sjeff		prio = PRIO_MAX;
143112918Sjeff	if (prio < PRIO_MIN)
144112918Sjeff		prio = PRIO_MIN;
145112918Sjeff	if (setpriority(which, who, prio) < 0) {
146112918Sjeff		warn("%d: setpriority", who);
147112918Sjeff		return (1);
148112918Sjeff	}
149112918Sjeff	fprintf(stderr, "%d: old priority %d, new priority %d\n", who,
150112918Sjeff	    oldprio, prio);
151112918Sjeff	return (0);
152112918Sjeff}
153112918Sjeff
154112918Sjeffstatic int
155112918Sjeffgetnum(const char *com, const char *str, int *val)
156112918Sjeff{
157112918Sjeff	long v;
158112918Sjeff	char *ep;
159112918Sjeff
160112918Sjeff	errno = 0;
161112918Sjeff	v = strtol(str, &ep, 10);
162112918Sjeff	if (v < INT_MIN || v > INT_MAX || errno == ERANGE) {
163112918Sjeff		warnx("%s argument %s is out of range.", com, str);
164112918Sjeff		return (1);
165112918Sjeff	}
166112918Sjeff	if (ep == str || *ep != '\0' || errno != 0) {
167115035Smtm		warnx("Bad %s argument: %s.", com, str);
168112918Sjeff		return (1);
169112918Sjeff	}
170112918Sjeff
171112918Sjeff	*val = (int)v;
172112918Sjeff	return (0);
173112918Sjeff}
174112918Sjeff
175112918Sjeffstatic void
176112918Sjeffusage(void)
177112918Sjeff{
178112918Sjeff	fprintf(stderr, "%s\n%s\n",
179112918Sjeff"usage: renice priority [[-p] pid ...] [[-g] pgrp ...] [[-u] user ...]",
180115035Smtm"       renice -n increment [[-p] pid ...] [[-g] pgrp ...] [[-u] user ...]");
181115035Smtm	exit(1);
182115035Smtm}
183115035Smtm