Annotation of src/usr.bin/renice/renice.c, Revision 1.13
1.13 ! millert 1: /* $OpenBSD: renice.c,v 1.12 2007/03/16 16:36:06 jmc 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.13 ! millert 20: static const char rcsid[] = "$OpenBSD: renice.c,v 1.12 2007/03/16 16:36:06 jmc 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. */
! 66: if (isdigit((unsigned char)argv[1][0])) {
! 67: argv[0] = "-n";
! 68: argc++;
! 69: argv--;
! 70: }
! 71:
! 72: /*
! 73: * Slightly tricky getopt() usage since it is legal to have
! 74: * option flags interleaved with arguments.
! 75: */
! 76: for (;;) {
! 77: if ((ch = getopt(argc, argv, "g:n:p:u:")) != -1) {
! 78: switch (ch) {
! 79: case 'g':
! 80: type = PRIO_PGRP;
! 81: idstr = optarg;
! 82: break;
! 83: case 'n':
! 84: l = strtol(optarg, &ep, 10);
! 85: if (*ep != '\0' || ep == optarg) {
! 86: warnx("invalid increment %s", optarg);
! 87: usage();
! 88: }
! 89: pri = l > PRIO_MAX ? PRIO_MAX :
! 90: l < PRIO_MIN ? PRIO_MIN : (int)l;
! 91:
! 92: /* Set priority for previous entries? */
! 93: if (!nflag) {
! 94: struct renice_param *pp;
! 95: for (pp = params; pp != p; pp++) {
! 96: pp->pri = pri;
! 97: }
! 98: }
! 99: nflag = 1;
! 100: continue;
! 101: case 'p':
! 102: type = PRIO_PROCESS;
! 103: idstr = optarg;
! 104: break;
! 105: case 'u':
! 106: type = PRIO_USER;
! 107: idstr = optarg;
! 108: break;
! 109: default:
! 110: usage();
! 111: break;
! 112: }
! 113: } else {
! 114: idstr = argv[optind++];
! 115: if (idstr == NULL)
! 116: break;
1.1 deraadt 117: }
1.13 ! millert 118: p->type = type;
! 119: p->pri = pri;
! 120: if (type == PRIO_USER) {
! 121: if ((pw = getpwnam(idstr)) == NULL) {
! 122: uid_t id = strtonum(idstr, 0, UID_MAX, &errstr);
! 123: if (!errstr)
! 124: pw = getpwuid(id);
! 125: }
! 126: if (pw == NULL) {
! 127: warnx("unknown user %s", idstr);
1.1 deraadt 128: continue;
129: }
1.13 ! millert 130: p->id = pw->pw_uid;
1.1 deraadt 131: } else {
1.13 ! millert 132: p->id = strtonum(idstr, 0, UINT_MAX, &errstr);
! 133: if (errstr) {
! 134: warnx("%s is %s", idstr, errstr);
1.1 deraadt 135: continue;
136: }
137: }
1.13 ! millert 138: p++;
1.1 deraadt 139: }
1.13 ! millert 140: if (!nflag)
! 141: usage();
! 142: exit(renice(params, p));
1.1 deraadt 143: }
144:
1.13 ! millert 145: static int
! 146: renice(struct renice_param *p, struct renice_param *end)
1.1 deraadt 147: {
1.13 ! millert 148: int old, errors = 0;
1.1 deraadt 149:
1.13 ! millert 150: for (; p < end; p++) {
! 151: errno = 0;
! 152: old = getpriority(p->type, p->id);
! 153: if (errno) {
! 154: warn("getpriority: %d", p->id);
! 155: errors++;
! 156: continue;
! 157: }
! 158: if (setpriority(p->type, p->id, p->pri) == -1) {
! 159: warn("setpriority: %d", p->id);
! 160: errors++;
! 161: continue;
! 162: }
! 163: printf("%d: old priority %d, new priority %d\n",
! 164: p->id, old, p->pri);
1.1 deraadt 165: }
1.13 ! millert 166: return (errors);
1.5 millert 167: }
168:
1.13 ! millert 169: __dead void
1.10 deraadt 170: usage(void)
1.5 millert 171: {
1.13 ! millert 172: fprintf(stderr, "usage: renice -n increment [[-g] pgrp ...] "
! 173: "[[-p] pid ...] [[-u] user ...]\n");
1.5 millert 174: exit(1);
1.1 deraadt 175: }