renice.c (3344B)
- // utils-std: Collection of commonly available Unix tools
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #define _XOPEN_SOURCE 700 // getpriority, setpriority
- #include <assert.h>
- #include <errno.h>
- #include <stdio.h> // fprintf
- #include <stdlib.h> // abort
- #include <string.h> // strerror
- #include <sys/resource.h> // getpriority, setpriority
- #include <unistd.h> // getopt, nice
- static int
- renice(int which, id_t who, int adj)
- {
- const char *which_s = NULL;
- switch(which)
- {
- case PRIO_PROCESS:
- which_s = "PRIO_PROCESS";
- break;
- case PRIO_PGRP:
- which_s = "PRIO_PGRP";
- break;
- case PRIO_USER:
- which_s = "PRIO_USER";
- break;
- default:
- which_s = NULL;
- }
- errno = 0;
- int prio = getpriority(which, who);
- if(errno != 0)
- {
- fprintf(stderr, "renice: error: getpriority(%s, %d): %s\n", which_s, who, strerror(errno));
- return -1;
- }
- prio += adj;
- if(setpriority(which, who, prio) != 0)
- {
- fprintf(stderr,
- "renice: error: setpriority(%s, %d, %d): %s\n",
- which_s,
- who,
- prio,
- strerror(errno));
- return -1;
- }
- return 0;
- }
- static void
- usage(void)
- {
- fprintf(stderr, "\
- Usage: renice [-p] -n adj PID...\n\
- renice -g -n adj PGID...\n\
- renice -u -n adj UID...\n\
- ");
- }
- int
- main(int argc, char *argv[])
- {
- long adj = 0;
- int which = PRIO_PROCESS;
- int c = -1;
- while((c = getopt(argc, argv, ":gpun:")) != -1)
- {
- switch(c)
- {
- case 'g':
- which = PRIO_PGRP;
- break;
- case 'p':
- which = PRIO_PROCESS;
- break;
- case 'u':
- which = PRIO_USER;
- break;
- case 'n':
- assert(errno == 0);
- char *endptr = NULL;
- adj = strtol(optarg, &endptr, 10);
- if(endptr && *endptr != 0) errno = EINVAL;
- if(errno != 0)
- {
- fprintf(stderr,
- "renice: error: Failed parsing '%s' as a number: %s\n",
- optarg,
- strerror(errno));
- usage();
- return 1;
- }
- if(adj < PRIO_MIN)
- {
- fprintf(stderr, "renice: error: '-n %ld' is lower than PRIO_MIN(%d)\n", adj, PRIO_MIN);
- return 1;
- }
- if(adj > PRIO_MAX)
- {
- fprintf(stderr, "renice: error: '-n %ld' is greater than PRIO_MAX(%d)\n", adj, PRIO_MAX);
- return 1;
- }
- if(adj == 0)
- {
- fprintf(stderr, "renice: error: '-n 0' makes no sense\n");
- return 1;
- }
- break;
- case ':':
- fprintf(stderr, "renice: error: Missing operand for option: '-%c'\n", optopt);
- usage();
- return 1;
- case '?':
- fprintf(stderr, "renice: error: Unrecognised option: '-%c'\n", optopt);
- usage();
- return 1;
- default:
- abort();
- }
- }
- argc -= optind;
- argv += optind;
- if(argc == 0)
- {
- fprintf(stderr, "renice: error: No IDs passed\n");
- usage();
- return 1;
- }
- if(adj == 0)
- {
- fprintf(stderr, "renice: error: Mandatory option '-n adj' not passed\n");
- usage();
- return 1;
- }
- for(int i = 0; i < argc; i++)
- {
- char *endptr = NULL;
- char *arg = argv[i];
- long who = strtol(arg, &endptr, 0);
- if(endptr && *endptr != 0) errno = EINVAL;
- if(errno != 0)
- {
- fprintf(stderr,
- "renice: error: Failed parsing argument '%s' as a number: %s\n",
- arg,
- strerror(errno));
- usage();
- return 1;
- }
- if(renice(which, who, adj) != 0) return 1;
- }
- return 0;
- }