commit: 1413ee0cb60c5ce1bc4cc67c6a24afc3ece9f9e4
parent 9028fdf9b20566fe6836fc72b8b28e4405f5f7b1
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Sun, 8 Sep 2024 02:16:18 +0200
cmd/renice: new
Diffstat:
M | cmd/nice.1 | 3 | +++ |
A | cmd/renice.1 | 56 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | cmd/renice.c | 168 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
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;
+}