]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
renice: support posix-compliant -n (via POSIXLY_CORRECT) and add --relative flag
authorDavid Anes <david.anes@suse.com>
Tue, 13 Dec 2022 10:02:36 +0000 (11:02 +0100)
committerDavid Anes <david.anes@suse.com>
Wed, 14 Dec 2022 12:38:24 +0000 (13:38 +0100)
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.

sys-utils/renice.1.adoc
sys-utils/renice.c

index 26392c2d7977345233c83a21a7c6ece9e62cafe5..c0d41ff15742a287a6263b447071859018fce4af 100644 (file)
@@ -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.
index 080b86e0bb302ea3a77202484d076885a8209c2e..177aab4b1208cc90d3751d82b35847b146988aed 100644 (file)
@@ -59,16 +59,22 @@ static void __attribute__((__noreturn__)) usage(void)
        FILE *out = stdout;
        fputs(USAGE_HEADER, out);
        fprintf(out,
-             _(" %1$s [-n] <priority> [-p|--pid] <pid>...\n"
-               " %1$s [-n] <priority>  -g|--pgrp <pgid>...\n"
-               " %1$s [-n] <priority>  -u|--user <user>...\n"),
+             _(" %1$s [-n|--priority|--relative] <priority> [-p|--pid] <pid>...\n"
+               " %1$s [-n|--priority|--relative] <priority>  -g|--pgrp <pgid>...\n"
+               " %1$s [-n|--priority|--relative] <priority>  -u|--user <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 <num>   specify the nice value\n"), out);
+       fputs(_(" -n <num>               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 <num>       specify the 'absolute' nice value\n"), out);
+       fputs(_(" --relative <num>       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;
 }