Annotation of src/usr.bin/renice/renice.c, Revision 1.14
1.14 ! millert 1: /* $OpenBSD: renice.c,v 1.13 2008/12/08 21:23:10 millert Exp $ */
1.2 deraadt 2:
1.1 deraadt 3: /*
1.13 millert 4: * Copyright (c) 2009 Todd C. Miller <Todd.Miller@courtesan.com>
1.1 deraadt 5: *
1.13 millert 6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
1.1 deraadt 9: *
1.13 millert 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 deraadt 17: */
18:
19: #ifndef lint
1.14 ! millert 20: static const char rcsid[] = "$OpenBSD: renice.c,v 1.13 2008/12/08 21:23:10 millert Exp $";
1.1 deraadt 21: #endif /* not lint */
22:
23: #include <sys/types.h>
24: #include <sys/time.h>
25: #include <sys/resource.h>
1.5 millert 26:
1.13 millert 27: #include <ctype.h>
28: #include <err.h>
29: #include <errno.h>
30: #include <limits.h>
31: #include <pwd.h>
1.1 deraadt 32: #include <stdio.h>
1.3 deraadt 33: #include <stdlib.h>
1.11 david 34: #include <string.h>
1.13 millert 35:
36: struct renice_param {
37: int pri;
38: int type;
39: id_t id;
40: };
1.1 deraadt 41:
1.8 millert 42: int main(int, char **);
1.13 millert 43: static int renice(struct renice_param *, struct renice_param *);
44: __dead void usage(void);
1.3 deraadt 45:
46: int
1.13 millert 47: main(int argc, char **argv)
1.1 deraadt 48: {
1.13 millert 49: struct renice_param *params, *p;
50: struct passwd *pw;
51: int ch, type = PRIO_PROCESS;
52: int nflag = 0, pri = 0;
53: char *ep, *idstr;
54: const char *errstr;
55: long l;
1.1 deraadt 56:
1.13 millert 57: if (argc < 3)
1.5 millert 58: usage();
1.13 millert 59:
60: /* Allocate enough space for the worst case. */
61: params = p = calloc(argc - 1, sizeof(*params));
62: if (params == NULL)
63: err(1, NULL);
64:
65: /* Backwards compatibility: first arg may be priority. */
1.14 ! millert 66: if (isdigit((unsigned char)argv[1][0]) ||
! 67: (argv[1][0] == '-' && isdigit((unsigned char)argv[1][1]))) {
1.13 millert 68: argv[0] = "-n";
69: argc++;
70: argv--;
71: }
72:
73: /*
74: * Slightly tricky getopt() usage since it is legal to have
75: * option flags interleaved with arguments.
76: */
77: for (;;) {
78: if ((ch = getopt(argc, argv, "g:n:p:u:")) != -1) {
79: switch (ch) {
80: case 'g':
81: type = PRIO_PGRP;
82: idstr = optarg;
83: break;
84: case 'n':
85: l = strtol(optarg, &ep, 10);
86: if (*ep != '\0' || ep == optarg) {
87: warnx("invalid increment %s", optarg);
88: usage();
89: }
90: pri = l > PRIO_MAX ? PRIO_MAX :
91: l < PRIO_MIN ? PRIO_MIN : (int)l;
92:
93: /* Set priority for previous entries? */
94: if (!nflag) {
95: struct renice_param *pp;
96: for (pp = params; pp != p; pp++) {
97: pp->pri = pri;
98: }
99: }
100: nflag = 1;
101: continue;
102: case 'p':
103: type = PRIO_PROCESS;
104: idstr = optarg;
105: break;
106: case 'u':
107: type = PRIO_USER;
108: idstr = optarg;
109: break;
110: default:
111: usage();
112: break;
113: }
114: } else {
115: idstr = argv[optind++];
116: if (idstr == NULL)
117: break;
1.1 deraadt 118: }
1.13 millert 119: p->type = type;
120: p->pri = pri;
121: if (type == PRIO_USER) {
122: if ((pw = getpwnam(idstr)) == NULL) {
123: uid_t id = strtonum(idstr, 0, UID_MAX, &errstr);
124: if (!errstr)
125: pw = getpwuid(id);
126: }
127: if (pw == NULL) {
128: warnx("unknown user %s", idstr);
1.1 deraadt 129: continue;
130: }
1.13 millert 131: p->id = pw->pw_uid;
1.1 deraadt 132: } else {
1.13 millert 133: p->id = strtonum(idstr, 0, UINT_MAX, &errstr);
134: if (errstr) {
135: warnx("%s is %s", idstr, errstr);
1.1 deraadt 136: continue;
137: }
138: }
1.13 millert 139: p++;
1.1 deraadt 140: }
1.13 millert 141: if (!nflag)
142: usage();
143: exit(renice(params, p));
1.1 deraadt 144: }
145:
1.13 millert 146: static int
147: renice(struct renice_param *p, struct renice_param *end)
1.1 deraadt 148: {
1.13 millert 149: int old, errors = 0;
1.1 deraadt 150:
1.13 millert 151: for (; p < end; p++) {
152: errno = 0;
153: old = getpriority(p->type, p->id);
154: if (errno) {
155: warn("getpriority: %d", p->id);
156: errors++;
157: continue;
158: }
159: if (setpriority(p->type, p->id, p->pri) == -1) {
160: warn("setpriority: %d", p->id);
161: errors++;
162: continue;
163: }
164: printf("%d: old priority %d, new priority %d\n",
165: p->id, old, p->pri);
1.1 deraadt 166: }
1.13 millert 167: return (errors);
1.5 millert 168: }
169:
1.13 millert 170: __dead void
1.10 deraadt 171: usage(void)
1.5 millert 172: {
1.13 millert 173: fprintf(stderr, "usage: renice -n increment [[-g] pgrp ...] "
174: "[[-p] pid ...] [[-u] user ...]\n");
1.5 millert 175: exit(1);
1.1 deraadt 176: }