[BACK]Return to renice.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / renice

Annotation of src/usr.bin/renice/renice.c, Revision 1.21

1.21    ! millert     1: /*     $OpenBSD: renice.c,v 1.20 2016/09/19 20:20:38 bluhm Exp $       */
1.2       deraadt     2:
1.1       deraadt     3: /*
1.21    ! millert     4:  * Copyright (c) 2009, 2015 Todd C. Miller <millert@openbsd.org>
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: #include <sys/types.h>
                     20: #include <sys/time.h>
                     21: #include <sys/resource.h>
1.5       millert    22:
1.13      millert    23: #include <ctype.h>
                     24: #include <err.h>
                     25: #include <errno.h>
                     26: #include <limits.h>
                     27: #include <pwd.h>
1.1       deraadt    28: #include <stdio.h>
1.3       deraadt    29: #include <stdlib.h>
1.11      david      30: #include <string.h>
1.16      millert    31: #include <unistd.h>
1.13      millert    32:
1.17      millert    33: #define        RENICE_NONE             0
                     34: #define        RENICE_ABSOLUTE         1
                     35: #define        RENICE_INCREMENT        2
                     36:
1.13      millert    37: struct renice_param {
                     38:        int pri;
1.17      millert    39:        short pri_type;
                     40:        short id_type;
1.13      millert    41:        id_t id;
                     42: };
1.1       deraadt    43:
1.8       millert    44: int main(int, char **);
1.13      millert    45: static int renice(struct renice_param *, struct renice_param *);
                     46: __dead void usage(void);
1.3       deraadt    47:
                     48: int
1.13      millert    49: main(int argc, char **argv)
1.1       deraadt    50: {
1.13      millert    51:        struct renice_param *params, *p;
                     52:        struct passwd *pw;
1.17      millert    53:        int ch, id_type = PRIO_PROCESS;
                     54:        int pri = 0, pri_type = RENICE_NONE;
1.13      millert    55:        char *ep, *idstr;
                     56:        const char *errstr;
1.19      deraadt    57:
                     58:        if (pledge("stdio getpw proc", NULL) == -1)
                     59:                err(1, "pledge");
1.1       deraadt    60:
1.13      millert    61:        if (argc < 3)
1.5       millert    62:                usage();
1.13      millert    63:
                     64:        /* Allocate enough space for the worst case. */
1.17      millert    65:        params = p = reallocarray(NULL, argc - 1, sizeof(*params));
1.13      millert    66:        if (params == NULL)
                     67:                err(1, NULL);
                     68:
                     69:        /* Backwards compatibility: first arg may be priority. */
1.14      millert    70:        if (isdigit((unsigned char)argv[1][0]) ||
1.17      millert    71:            ((argv[1][0] == '+' || argv[1][0] == '-') &&
                     72:            isdigit((unsigned char)argv[1][1]))) {
                     73:                pri = (int)strtol(argv[1], &ep, 10);
                     74:                if (*ep != '\0' || ep == argv[1]) {
                     75:                        warnx("invalid priority %s", argv[1]);
                     76:                        usage();
                     77:                }
                     78:                pri_type = RENICE_ABSOLUTE;
                     79:                optind = 2;
1.13      millert    80:        }
                     81:
                     82:        /*
                     83:         * Slightly tricky getopt() usage since it is legal to have
                     84:         * option flags interleaved with arguments.
                     85:         */
                     86:        for (;;) {
                     87:                if ((ch = getopt(argc, argv, "g:n:p:u:")) != -1) {
                     88:                        switch (ch) {
                     89:                        case 'g':
1.17      millert    90:                                id_type = PRIO_PGRP;
1.13      millert    91:                                idstr = optarg;
                     92:                                break;
                     93:                        case 'n':
1.17      millert    94:                                pri = (int)strtol(optarg, &ep, 10);
1.13      millert    95:                                if (*ep != '\0' || ep == optarg) {
                     96:                                        warnx("invalid increment %s", optarg);
                     97:                                        usage();
                     98:                                }
                     99:
                    100:                                /* Set priority for previous entries? */
1.17      millert   101:                                if (pri_type == RENICE_NONE) {
1.13      millert   102:                                        struct renice_param *pp;
                    103:                                        for (pp = params; pp != p; pp++) {
                    104:                                                pp->pri = pri;
1.17      millert   105:                                                pp->pri_type = RENICE_INCREMENT;
1.13      millert   106:                                        }
                    107:                                }
1.17      millert   108:                                pri_type = RENICE_INCREMENT;
1.13      millert   109:                                continue;
                    110:                        case 'p':
1.17      millert   111:                                id_type = PRIO_PROCESS;
1.13      millert   112:                                idstr = optarg;
                    113:                                break;
                    114:                        case 'u':
1.17      millert   115:                                id_type = PRIO_USER;
1.13      millert   116:                                idstr = optarg;
                    117:                                break;
                    118:                        default:
                    119:                                usage();
                    120:                                break;
                    121:                        }
                    122:                } else {
                    123:                        idstr = argv[optind++];
                    124:                        if (idstr == NULL)
                    125:                                break;
1.1       deraadt   126:                }
1.17      millert   127:                p->id_type = id_type;
1.13      millert   128:                p->pri = pri;
1.17      millert   129:                p->pri_type = pri_type;
                    130:                if (id_type == PRIO_USER) {
1.13      millert   131:                        if ((pw = getpwnam(idstr)) == NULL) {
                    132:                                uid_t id = strtonum(idstr, 0, UID_MAX, &errstr);
                    133:                                if (!errstr)
                    134:                                        pw = getpwuid(id);
                    135:                        }
                    136:                        if (pw == NULL) {
                    137:                                warnx("unknown user %s", idstr);
1.1       deraadt   138:                                continue;
                    139:                        }
1.13      millert   140:                        p->id = pw->pw_uid;
1.1       deraadt   141:                } else {
1.13      millert   142:                        p->id = strtonum(idstr, 0, UINT_MAX, &errstr);
                    143:                        if (errstr) {
                    144:                                warnx("%s is %s", idstr, errstr);
1.1       deraadt   145:                                continue;
                    146:                        }
                    147:                }
1.13      millert   148:                p++;
1.1       deraadt   149:        }
1.17      millert   150:        if (pri_type == RENICE_NONE)
1.13      millert   151:                usage();
1.20      bluhm     152:        return(renice(params, p));
1.1       deraadt   153: }
                    154:
1.13      millert   155: static int
                    156: renice(struct renice_param *p, struct renice_param *end)
1.1       deraadt   157: {
1.17      millert   158:        int new, old, errors = 0;
1.1       deraadt   159:
1.13      millert   160:        for (; p < end; p++) {
                    161:                errno = 0;
1.17      millert   162:                old = getpriority(p->id_type, p->id);
1.13      millert   163:                if (errno) {
                    164:                        warn("getpriority: %d", p->id);
                    165:                        errors++;
                    166:                        continue;
                    167:                }
1.17      millert   168:                if (p->pri_type == RENICE_INCREMENT)
                    169:                        p->pri += old;
                    170:                new = p->pri > PRIO_MAX ? PRIO_MAX :
                    171:                    p->pri < PRIO_MIN ? PRIO_MIN : p->pri;
                    172:                if (setpriority(p->id_type, p->id, new) == -1) {
1.13      millert   173:                        warn("setpriority: %d", p->id);
                    174:                        errors++;
                    175:                        continue;
                    176:                }
                    177:                printf("%d: old priority %d, new priority %d\n",
1.17      millert   178:                    p->id, old, new);
1.1       deraadt   179:        }
1.13      millert   180:        return (errors);
1.5       millert   181: }
                    182:
1.13      millert   183: __dead void
1.10      deraadt   184: usage(void)
1.5       millert   185: {
1.18      jmc       186:        fprintf(stderr, "usage: renice [-n] increment [-gpu] id\n");
1.5       millert   187:        exit(1);
1.1       deraadt   188: }