From: David Anes Date: Tue, 13 Dec 2022 10:02:36 +0000 (+0100) Subject: renice: support posix-compliant -n (via POSIXLY_CORRECT) and add --relative flag X-Git-Tag: v2.39-rc1~219^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=56ce8f610367c6fb5847060b39a06ecfcbf0f0ca;p=thirdparty%2Futil-linux.git renice: support posix-compliant -n (via POSIXLY_CORRECT) and add --relative flag As noted in bug #1892, renice is not 100% posix compliant as the '-n' option should update the priority 'relative' to the current priority. As such change would break compatibility, the current approach was taken: - donice() has now a new param to denote if priority is absolute or relative. - main() interprets '-n' as absolute if environment variable POSIXLY_CORRECT is **not set**. Otherwise, it uses a relative value, as POSIX mandates. - The option '--priority' is left as it is: uses an absolute value. - A new option '--relative' is added, should a user want a posix compatible variant without setting up an environment variable. - manpage is updated to display all these changes. After this patch: - Calling renice with '-n 2' on a process with current priority '2' and POSIXLY_CORRECT, will try to update it to priority '4', instead of '2'. - Calling renice with '--priority 2' on a process with current priority '2', leaves the process at priority '2'. - Calling renice with '--relative 2' on a process with current priority '2' will try to update the it to priority '4', regardless of environment flags. --- diff --git a/sys-utils/renice.1.adoc b/sys-utils/renice.1.adoc index 26392c2d79..c0d41ff157 100644 --- a/sys-utils/renice.1.adoc +++ b/sys-utils/renice.1.adoc @@ -46,16 +46,24 @@ renice - alter priority of running processes == SYNOPSIS -*renice* [*-n*] _priority_ [*-g*|*-p*|*-u*] _identifier_... +*renice* [*--priority|--relative*] _priority_ [*-g*|*-p*|*-u*] _identifier_... == DESCRIPTION *renice* alters the scheduling priority of one or more running processes. The first argument is the _priority_ value to be used. The other arguments are interpreted as process IDs (by default), process group IDs, user IDs, or user names. *renice*'ing a process group causes all processes in the process group to have their scheduling priority altered. *renice*'ing a user causes all processes owned by the user to have their scheduling priority altered. +If no *-n*, *--priority* or *--relative* option is used, then the priority is set as *absolute*. + == OPTIONS -*-n*, *--priority* _priority_:: -Specify the scheduling _priority_ to be used for the process, process group, or user. Use of the option *-n* or *--priority* is optional, but when used it must be the first argument. +*-n* _priority_:: +Specify the *absolute* or *relative* (depending on environment variable POSIXLY_CORRECT) scheduling _priority_ to be used for the process, process group, or user. Use of the option *-n* is optional, but when used it must be the first argument. See *NOTES* for more information. + +*--priority* _priority_:: +Specify an *absolute* scheduling _priority_. _Priority_ is set to the given value. This is the default, when no option is specified. + +*--relative* _priority_:: +Specify a *relative* scheduling _priority_. Same a the standard POSIX *-n* option. _Priority_ gets _incremented/decremented_ by the given value. *-g*, *--pgrp*:: Interpret the succeeding arguments as process group IDs. @@ -79,6 +87,8 @@ Users other than the superuser may only alter the priority of processes they own The superuser may alter the priority of any process and set the priority to any value in the range -20 to 19. Useful priorities are: 19 (the affected processes will run only when nothing else in the system wants to), 0 (the "base" scheduling priority), anything negative (to make things go very fast). +For historical reasons in this implementation, the *-n* option did not follow the POSIX specification, therefore instead of setting a *relative* priority it sets an *absolute* priority by default. As this may not be desirable, this behavior can be controlled by setting the environment variable POSIXLY_CORRECT to be fully POSIX compliant. See *-n* option for details. See *--relative* and *--priority* for options that don't change behavior depending on environment variables. + == HISTORY The *renice* command appeared in 4.0BSD. diff --git a/sys-utils/renice.c b/sys-utils/renice.c index 080b86e0bb..177aab4b12 100644 --- a/sys-utils/renice.c +++ b/sys-utils/renice.c @@ -59,16 +59,22 @@ static void __attribute__((__noreturn__)) usage(void) FILE *out = stdout; fputs(USAGE_HEADER, out); fprintf(out, - _(" %1$s [-n] [-p|--pid] ...\n" - " %1$s [-n] -g|--pgrp ...\n" - " %1$s [-n] -u|--user ...\n"), + _(" %1$s [-n|--priority|--relative] [-p|--pid] ...\n" + " %1$s [-n|--priority|--relative] -g|--pgrp ...\n" + " %1$s [-n|--priority|--relative] -u|--user ...\n"), program_invocation_short_name); fputs(USAGE_SEPARATOR, out); fputs(_("Alter the priority of running processes.\n"), out); fputs(USAGE_OPTIONS, out); - fputs(_(" -n, --priority specify the nice value\n"), out); + fputs(_(" -n specify the nice value\n"), out); + fputs(_(" If POSIXLY_CORRECT flag is set in environment\n"), out); + fputs(_(" environment then the priority is 'relative'\n"), out); + fputs(_(" to current process priority. Otherwise it is\n"), out); + fputs(_(" 'absolute'.\n"), out); + fputs(_(" --priority specify the 'absolute' nice value\n"), out); + fputs(_(" --relative specify the 'relative' nice value\n"), out); fputs(_(" -p, --pid interpret arguments as process ID (default)\n"), out); fputs(_(" -g, --pgrp interpret arguments as process group ID\n"), out); fputs(_(" -u, --user interpret arguments as username or user ID\n"), out); @@ -89,13 +95,18 @@ static int getprio(const int which, const int who, int *prio) return 0; } -static int donice(const int which, const int who, const int prio) +static int donice(const int which, const int who, const int prio, const int relative) { int oldprio, newprio; if (getprio(which, who, &oldprio) != 0) return 1; - if (setpriority(which, who, prio) < 0) { + + newprio = oldprio; + if (relative) + newprio += prio; + + if (setpriority(which, who, newprio) < 0) { warn(_("failed to set priority for %d (%s)"), who, idtype[which]); return 1; } @@ -114,6 +125,7 @@ int main(int argc, char **argv) { int which = PRIO_PROCESS; int who = 0, prio, errs = 0; + int relative = 0; char *endptr = NULL; setlocale(LC_ALL, ""); @@ -135,9 +147,28 @@ int main(int argc, char **argv) print_version(EXIT_SUCCESS); } - if (*argv && (strcmp(*argv, "-n") == 0 || strcmp(*argv, "--priority") == 0)) { - argc--; - argv++; + if (*argv) + { + if (strcmp(*argv, "-n") == 0) + { + // Fully conform to posix only if POSIXLY_CORRECT is + // set in the environment. If not, use the absolute + // value as it's been used (incorrectly) since 2009 + relative = getenv("POSIXLY_CORRECT") == NULL ? 0 : 1; + argc--; + argv++; + } + else if (strcmp(*argv, "--relative") == 0) + { + relative = 1; + argc--; + argv++; + } + else if (strcmp(*argv, "--priority") == 0) { + relative = 0; + argc--; + argv++; + } } if (argc < 2 || !*argv) { @@ -188,7 +219,7 @@ int main(int argc, char **argv) continue; } } - errs |= donice(which, who, prio); + errs |= donice(which, who, prio, relative); } return errs != 0 ? EXIT_FAILURE : EXIT_SUCCESS; }