]> err.no Git - util-linux/commitdiff
ionice: add strtol() checks, cleanup usage text and man page
authorKarel Zak <kzak@redhat.com>
Sat, 6 Sep 2008 12:54:01 +0000 (14:54 +0200)
committerKarel Zak <kzak@redhat.com>
Sat, 6 Sep 2008 12:54:01 +0000 (14:54 +0200)
 * 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>
schedutils/ionice.1
schedutils/ionice.c

index 67fbc1d044c1a8f7644d1b4aad88ff42b14f4627..2eca2b8b19a642382af478b261b95ef5f65468d6 100644 (file)
@@ -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.
 
index 2331bec4f8c57a68de76401cad88c446a4b14be5..d41a8fad472175e666b221d487ba9ba23c5e3739 100644 (file)
@@ -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"));
                }
        }