diff options
author | Karel Zak | 2008-09-06 14:54:01 +0200 |
---|---|---|
committer | Karel Zak | 2008-09-06 14:54:01 +0200 |
commit | 030d18fd2a75784359a970d0560446952575f024 (patch) | |
tree | 83c481dee176e2033f648dd45ee053d5a9e7e8d2 /schedutils/ionice.c | |
parent | ionice: let -p handle multiple PIDs (diff) | |
download | kernel-qcow2-util-linux-030d18fd2a75784359a970d0560446952575f024.tar.gz kernel-qcow2-util-linux-030d18fd2a75784359a970d0560446952575f024.tar.xz kernel-qcow2-util-linux-030d18fd2a75784359a970d0560446952575f024.zip |
ionice: add strtol() checks, cleanup usage text and man page
* cleanup usage() output
* check strtol(); don't ignore wrong command line options
The original ionice design was a little broken, because it was
possible to specify a PID and also a COMMAND:
ionice -c2 -p 123 /bin/foo
but the command /bin/foo was executed without requested scheduling
class. That's stupid behaviour.
Now you have to use "-p PID" **or** COMMAND, but not both. Nothing is
ignored and all options are checked.
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'schedutils/ionice.c')
-rw-r--r-- | schedutils/ionice.c | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/schedutils/ionice.c b/schedutils/ionice.c index 2331bec4f..d41a8fad4 100644 --- a/schedutils/ionice.c +++ b/schedutils/ionice.c @@ -78,22 +78,45 @@ static void ioprio_setpid(pid_t pid, int ioprio, int ioclass) static void usage(int rc) { fprintf(stdout, _( - "\nionice - sets or gets process io scheduling class and priority.\n\n" - "Usage: ionice [OPTIONS] [COMMAND [ARG]...]\n\n" + "\nionice - sets or gets process io scheduling class and priority.\n" + "\nUsage:\n" + " ionice [ options ] -p <pid> [<pid> ...]\n" + " ionoce [ options ] <command> [<arg> ...]\n" + "\nOptions:\n" " -n <classdata> class data (0-7, lower being higher prio)\n" " -c <class> scheduling class\n" " 1: realtime, 2: best-effort, 3: idle\n" - " -p <pid> process pid\n" - " -t ignore failures, run command unconditionally\n" + " -t ignore failures\n" " -h this help\n\n")); - exit(rc); } +static long getnum(const char *str) +{ + long num; + char *end = NULL; + + if (str == NULL || *str == '\0') + goto err; + errno = 0; + num = strtol(str, &end, 10); + + if (errno || (end && *end)) + goto err; + + return num; +err: + if (errno) + err(EXIT_SUCCESS, _("cannot parse number '%s'"), str); + else + errx(EXIT_SUCCESS, _("cannot parse number '%s'"), str); + return 0; +} + int main(int argc, char *argv[]) { - int ioprio = 4, set = 0, ioclass = IOPRIO_CLASS_BE; - int c, pid = 0; + int ioprio = 4, set = 0, ioclass = IOPRIO_CLASS_BE, c; + pid_t pid = 0; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -102,15 +125,15 @@ int main(int argc, char *argv[]) while ((c = getopt(argc, argv, "+n:c:p:th")) != EOF) { switch (c) { case 'n': - ioprio = strtol(optarg, NULL, 10); + ioprio = getnum(optarg); set |= 1; break; case 'c': - ioclass = strtol(optarg, NULL, 10); + ioclass = getnum(optarg); set |= 2; break; case 'p': - pid = strtol(optarg, NULL, 10); + pid = getnum(optarg); break; case 't': tolerant = 1; @@ -142,7 +165,7 @@ int main(int argc, char *argv[]) ioprio_print(pid); for(; argv[optind]; ++optind) { - pid = strtol(argv[optind], NULL, 10); + pid = getnum(argv[optind]); ioprio_print(pid); } } else { @@ -151,16 +174,15 @@ int main(int argc, char *argv[]) for(; argv[optind]; ++optind) { - pid = strtol(argv[optind], NULL, 10); + pid = getnum(argv[optind]); ioprio_setpid(pid, ioprio, ioclass); } - } else { + } + else if (argv[optind]) { ioprio_setpid(0, ioprio, ioclass); - if (argv[optind]) { - execvp(argv[optind], &argv[optind]); - /* execvp should never return */ - err(EXIT_FAILURE, _("execvp failed")); - } + execvp(argv[optind], &argv[optind]); + /* execvp should never return */ + err(EXIT_FAILURE, _("execvp failed")); } } |