/* See LICENSE file for copyright and license details. */ #include <sys/resource.h> #include <errno.h> #include <limits.h> #include <pwd.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "util.h" static int strtop(const char *); static bool renice(int, int, long); static void usage(void); int main(int argc, char **argv) { const char *adj = NULL; long val; int i, which = PRIO_PROCESS, status = EXIT_SUCCESS; ARGBEGIN { case 'n': adj = EARGF(usage()); break; case 'g': which = PRIO_PGRP; break; case 'p': which = PRIO_PROCESS; break; case 'u': which = PRIO_USER; break; default: usage(); break; } ARGEND; if(argc == 0 || !adj) usage(); val = estrtol(adj, 10); for(i = 0; i < argc; i++) { int who = -1; if(which == PRIO_USER) { const struct passwd *pwd; errno = 0; do pwd = getpwnam(argv[i]); while(errno == EINTR); if(pwd) who = pwd->pw_uid; else if(errno != 0) { perror("can't read passwd"); status = EXIT_FAILURE; continue; } } if(who < 0) who = strtop(argv[i]); if(who < 0 || !renice(which, who, val)) status = EXIT_FAILURE; } return status; } static int strtop(const char *s) { char *end; long n; errno = 0; n = strtol(s, &end, 10); if(*end != '\0') { fprintf(stderr, "%s: not an integer\n", s); return -1; } if(errno != 0 || n <= 0 || n > INT_MAX) { fprintf(stderr, "%s: invalid value\n", s); return -1; } return (int)n; } static bool renice(int which, int who, long adj) { errno = 0; adj += getpriority(which, who); if(errno != 0) { fprintf(stderr, "can't get %d nice level: %s\n", who, strerror(errno)); return false; } adj = MAX(PRIO_MIN, MIN(adj, PRIO_MAX)); if(setpriority(which, who, (int)adj) == -1) { fprintf(stderr, "can't set %d nice level: %s\n", who, strerror(errno)); return false; } return true; } static void usage(void) { eprintf("renice -n inc [-g | -p | -u] ID ...\n"); }