renice: fix argument order.

The target modifiers (-g, -p, -u) may occur in any position except
between -n and its argument; furthermore, we support both the old
absolute form (without -n) and the modern relative form (with -n).

Sponsored by: Klara, Inc.
This commit is contained in:
Dag-Erling Smørgrav 2022-08-25 17:22:37 +00:00
parent e621cb0be2
commit 65ee0a8495

View file

@ -52,11 +52,12 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <limits.h>
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int donice(int, int, int, int);
static int donice(int, int, int, bool);
static int getnum(const char *, const char *, int *);
static void usage(void);
@ -69,27 +70,12 @@ int
main(int argc, char *argv[])
{
struct passwd *pwd;
int delim, errs, incr, prio, which, who;
bool havedelim = false, haveprio = false, incr = false;
int errs = 0, prio = 0, who = 0, which = PRIO_PROCESS;
delim = 0;
errs = 0;
incr = 0;
which = PRIO_PROCESS;
who = 0;
argc--, argv++;
if (argc < 2)
usage();
if (strcmp(*argv, "-n") == 0) {
incr = 1;
argc--, argv++;
if (argc < 2)
usage();
}
if (getnum("priority", *argv, &prio))
return (1);
argc--, argv++;
for (; argc > 0; argc--, argv++) {
if (!delim) {
for (argc--, argv++; argc > 0; argc--, argv++) {
if (!havedelim) {
/* can occur at any time prior to delimiter */
if (strcmp(*argv, "-g") == 0) {
which = PRIO_PGRP;
continue;
@ -103,9 +89,24 @@ main(int argc, char *argv[])
continue;
}
if (strcmp(*argv, "--") == 0) {
delim = 1;
havedelim = true;
continue;
}
if (strcmp(*argv, "-n") == 0) {
/* may occur only once, prior to priority */
if (haveprio || incr)
usage();
incr = true;
(void)argc--, argv++;
/* fall through to priority */
}
}
if (!haveprio) {
/* must occur exactly once, prior to target */
if (getnum("priority", *argv, &prio))
return (1);
haveprio = true;
continue;
}
if (which == PRIO_USER) {
if ((pwd = getpwnam(*argv)) != NULL)
@ -131,11 +132,13 @@ main(int argc, char *argv[])
}
errs += donice(which, who, prio, incr);
}
if (!haveprio)
usage();
exit(errs != 0);
}
static int
donice(int which, int who, int prio, int incr)
donice(int which, int who, int prio, bool incr)
{
int oldprio;
@ -173,7 +176,7 @@ getnum(const char *com, const char *str, int *val)
return (1);
}
if (ep == str || *ep != '\0' || errno != 0) {
warnx("Bad %s argument: %s.", com, str);
warnx("%s argument %s is invalid.", com, str);
return (1);
}