diff --git a/schedutils/ionice.1 b/schedutils/ionice.1 index 67fbc1d04..2eca2b8b1 100644 --- a/schedutils/ionice.1 +++ b/schedutils/ionice.1 @@ -2,7 +2,9 @@ .SH NAME ionice \- get/set program io scheduling class and priority .SH SYNOPSIS -.BI "ionice [\-p " pid "] [\-c " class "] [\-n " classdata " ] [\-t] [COMMAND [ARG ...]]" +.BI "ionice [[\-c " class "] [\-n " classdata " ] [\-t]] \-p " PID " [" PID " ...]" + +.BI "ionice [\-c " class "] [\-n " classdata " ] [\-t] COMMAND [ARG ...]" .SH DESCRIPTION This program sets or gets the io scheduling class and priority for a program. @@ -41,11 +43,11 @@ The scheduling class data. This defines the class data, if the class accepts an argument. For real time and best-effort, \fI0-7\fR is valid data. .IP "\fB-p \fIpid\fP" -Pass in process PIDs to view or change already running processes. If this argument +Pass in process PID(s) to view or change already running processes. If this argument is not given, \fBionice\fP will run the listed program with the given parameters. .IP "\fB-t\fP" -Ignore failure to set requested priority. If COMMAND is specified, run it +Ignore failure to set requested priority. If COMMAND or PID(s) is specified, run it even in case it was not possible to set desired scheduling priority, what can happen due to insufficient privilegies or old kernel version. 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 [ ...]\n" + " ionoce [ options ] [ ...]\n" + "\nOptions:\n" " -n class data (0-7, lower being higher prio)\n" " -c scheduling class\n" " 1: realtime, 2: best-effort, 3: idle\n" - " -p 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")); } }