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>
This commit is contained in:
parent
ef0fe2e8aa
commit
030d18fd2a
|
@ -2,7 +2,9 @@
|
||||||
.SH NAME
|
.SH NAME
|
||||||
ionice \- get/set program io scheduling class and priority
|
ionice \- get/set program io scheduling class and priority
|
||||||
.SH SYNOPSIS
|
.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
|
.SH DESCRIPTION
|
||||||
This program sets or gets the io scheduling class and priority for a program.
|
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
|
accepts an argument. For real time and best-effort, \fI0-7\fR is valid
|
||||||
data.
|
data.
|
||||||
.IP "\fB-p \fIpid\fP"
|
.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
|
is not given, \fBionice\fP will run the listed program with the given
|
||||||
parameters.
|
parameters.
|
||||||
.IP "\fB-t\fP"
|
.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
|
even in case it was not possible to set desired scheduling priority, what
|
||||||
can happen due to insufficient privilegies or old kernel version.
|
can happen due to insufficient privilegies or old kernel version.
|
||||||
|
|
||||||
|
|
|
@ -78,22 +78,45 @@ static void ioprio_setpid(pid_t pid, int ioprio, int ioclass)
|
||||||
static void usage(int rc)
|
static void usage(int rc)
|
||||||
{
|
{
|
||||||
fprintf(stdout, _(
|
fprintf(stdout, _(
|
||||||
"\nionice - sets or gets process io scheduling class and priority.\n\n"
|
"\nionice - sets or gets process io scheduling class and priority.\n"
|
||||||
"Usage: ionice [OPTIONS] [COMMAND [ARG]...]\n\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"
|
" -n <classdata> class data (0-7, lower being higher prio)\n"
|
||||||
" -c <class> scheduling class\n"
|
" -c <class> scheduling class\n"
|
||||||
" 1: realtime, 2: best-effort, 3: idle\n"
|
" 1: realtime, 2: best-effort, 3: idle\n"
|
||||||
" -p <pid> process pid\n"
|
" -t ignore failures\n"
|
||||||
" -t ignore failures, run command unconditionally\n"
|
|
||||||
" -h this help\n\n"));
|
" -h this help\n\n"));
|
||||||
|
|
||||||
exit(rc);
|
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 main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int ioprio = 4, set = 0, ioclass = IOPRIO_CLASS_BE;
|
int ioprio = 4, set = 0, ioclass = IOPRIO_CLASS_BE, c;
|
||||||
int c, pid = 0;
|
pid_t pid = 0;
|
||||||
|
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
|
@ -102,15 +125,15 @@ int main(int argc, char *argv[])
|
||||||
while ((c = getopt(argc, argv, "+n:c:p:th")) != EOF) {
|
while ((c = getopt(argc, argv, "+n:c:p:th")) != EOF) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'n':
|
case 'n':
|
||||||
ioprio = strtol(optarg, NULL, 10);
|
ioprio = getnum(optarg);
|
||||||
set |= 1;
|
set |= 1;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
ioclass = strtol(optarg, NULL, 10);
|
ioclass = getnum(optarg);
|
||||||
set |= 2;
|
set |= 2;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
pid = strtol(optarg, NULL, 10);
|
pid = getnum(optarg);
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
tolerant = 1;
|
tolerant = 1;
|
||||||
|
@ -142,7 +165,7 @@ int main(int argc, char *argv[])
|
||||||
ioprio_print(pid);
|
ioprio_print(pid);
|
||||||
|
|
||||||
for(; argv[optind]; ++optind) {
|
for(; argv[optind]; ++optind) {
|
||||||
pid = strtol(argv[optind], NULL, 10);
|
pid = getnum(argv[optind]);
|
||||||
ioprio_print(pid);
|
ioprio_print(pid);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -151,16 +174,15 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
for(; argv[optind]; ++optind)
|
for(; argv[optind]; ++optind)
|
||||||
{
|
{
|
||||||
pid = strtol(argv[optind], NULL, 10);
|
pid = getnum(argv[optind]);
|
||||||
ioprio_setpid(pid, ioprio, ioclass);
|
ioprio_setpid(pid, ioprio, ioclass);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else if (argv[optind]) {
|
||||||
ioprio_setpid(0, ioprio, ioclass);
|
ioprio_setpid(0, ioprio, ioclass);
|
||||||
if (argv[optind]) {
|
execvp(argv[optind], &argv[optind]);
|
||||||
execvp(argv[optind], &argv[optind]);
|
/* execvp should never return */
|
||||||
/* execvp should never return */
|
err(EXIT_FAILURE, _("execvp failed"));
|
||||||
err(EXIT_FAILURE, _("execvp failed"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue