logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git
commit: 1413ee0cb60c5ce1bc4cc67c6a24afc3ece9f9e4
parent 9028fdf9b20566fe6836fc72b8b28e4405f5f7b1
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sun,  8 Sep 2024 02:16:18 +0200

cmd/renice: new

Diffstat:

Mcmd/nice.13+++
Acmd/renice.156++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acmd/renice.c168+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 227 insertions(+), 0 deletions(-)

diff --git a/cmd/nice.1 b/cmd/nice.1 @@ -48,6 +48,9 @@ was found but couldn't be invoked. .Ar command wasn't found. .El +.Sh SEE ALSO +.Xr renice 1 , +.Xr nice 3 .Sh STANDARDS .Nm should be compliant with the diff --git a/cmd/renice.1 b/cmd/renice.1 @@ -0,0 +1,56 @@ +.\" utils-std: Collection of commonly available Unix tools +.\" Copyright 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me> +.\" SPDX-License-Identifier: MPL-2.0 +.Dd 2024-09-08 +.Dt RENICE 1 +.Os +.Sh NAME +.Nm renice +.Nd modify scheduling priority of running processes +.Sh SYNOPSIS +.Nm +.Op Fl p +.Fl n Ar adj +.Ar PID... +.Nm +.Fl g +.Fl n Ar adj +.Ar PGID... +.Nm +.Fl u +.Fl n Ar adj +.Ar UID... +.Sh DESCRIPTION +.Nm +modifies the scheduling priority of running processes. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl g +Adjust all processes of each given process groups IDs +.Pq Ar PGID . +.It Fl n Ar adj +Positive or negative integer used to adjust the scheduling priority +of the process relative to it's current priority. +Negative +.Ar adj +may require appropriate privileges. +.It Fl p +Adjust each given process IDs +.Pq Ar PID . +(default) +.It Fl u +Adjust all processes of each given user IDs +.Pq Ar UID . +.El +.Sh EXIT STATUS +.Ex -std +.Sh SEE ALSO +.Xr nice 1 , +.Xr setpriority 3 +.Sh STANDARDS +.Nm +should be compliant with the +IEEE Std 1003.1-2024 (“POSIX.1”) +specification. +.Sh AUTHORS +.An Haelwenn (lanodan) Monnier Aq Mt contact+utils@hacktivis.me diff --git a/cmd/renice.c b/cmd/renice.c @@ -0,0 +1,168 @@ +// 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, int 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: getpriority(%s, %d): %s\n", which_s, who, strerror(errno)); + return -1; + } + + prio += adj; + + if(setpriority(which, who, prio) != 0) + { + fprintf(stderr, "renice: 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: 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; + } + + renice(which, who, adj); + } + + return 0; +}