chrt: do not segfault if policy number is unknown
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 5 Apr 2019 10:03:48 +0000 (12:03 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 5 Apr 2019 10:03:48 +0000 (12:03 +0200)
While at it, improve help text

function                                             old     new   delta
packed_usage                                       33319   33344     +25
policy_name                                            -      22     +22
show_min_max                                          59      64      +5
chrt_main                                            432     429      -3
policies                                              72       -     -72
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 2/1 up/down: 52/-75)            Total: -23 bytes
   text    data     bss     dec     hex filename
 982150     485    7296  989931   f1aeb busybox_old
 982183     485    7296  989964   f1b0c busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
util-linux/chrt.c

index 28e65457c5c010fe51a9da290c7e2b8fd3a50dc4..ede92310f13a57ac31841c9b6fd76eb65f01b0b4 100644 (file)
 //kbuild:lib-$(CONFIG_CHRT) += chrt.o
 
 //usage:#define chrt_trivial_usage
-//usage:       "[-prfombi] [PRIO] [PID | PROG ARGS]"
+//usage:       "-m | -p [PRIO] PID | [-rfobi] PRIO PROG [ARGS]"
 //usage:#define chrt_full_usage "\n\n"
 //usage:       "Change scheduling priority and class for a process\n"
+//usage:     "\n       -m      Show min/max priorities"
 //usage:     "\n       -p      Operate on PID"
 //usage:     "\n       -r      Set SCHED_RR class"
 //usage:     "\n       -f      Set SCHED_FIFO class"
 //usage:     "\n       -o      Set SCHED_OTHER class"
 //usage:     "\n       -b      Set SCHED_BATCH class"
 //usage:     "\n       -i      Set SCHED_IDLE class"
-//usage:     "\n       -m      Show min/max priorities"
 //usage:
 //usage:#define chrt_example_usage
 //usage:       "$ chrt -r 4 sleep 900; x=$!\n"
 # define SCHED_IDLE 5
 #endif
 
-static const struct {
-       char name[sizeof("SCHED_OTHER")];
-} policies[] = {
-       { "SCHED_OTHER" }, /* 0:SCHED_OTHER */
-       { "SCHED_FIFO" },  /* 1:SCHED_FIFO */
-       { "SCHED_RR" },    /* 2:SCHED_RR */
-       { "SCHED_BATCH" }, /* 3:SCHED_BATCH */
-       { "" },            /* 4:SCHED_ISO */
-       { "SCHED_IDLE" },  /* 5:SCHED_IDLE */
-       /* 6:SCHED_DEADLINE */
-};
+static const char *policy_name(int pol)
+{
+       if (pol > 6)
+               return utoa(pol);
+       return nth_string(
+               "OTHER"   "\0" /* 0:SCHED_OTHER */
+               "FIFO"    "\0" /* 1:SCHED_FIFO */
+               "RR"      "\0" /* 2:SCHED_RR */
+               "BATCH"   "\0" /* 3:SCHED_BATCH */
+               "ISO"     "\0" /* 4:SCHED_ISO */
+               "IDLE"    "\0" /* 5:SCHED_IDLE */
+               "DEADLINE",    /* 6:SCHED_DEADLINE */
+               pol
+       );
+}
 
 static void show_min_max(int pol)
 {
-       const char *fmt = "%s min/max priority\t: %u/%u\n";
+       const char *fmt = "SCHED_%s min/max priority\t: %u/%u\n";
        int max, min;
 
        max = sched_get_priority_max(pol);
        min = sched_get_priority_min(pol);
        if ((max|min) < 0)
-               fmt = "%s not supported\n";
-       printf(fmt, policies[pol].name, min, max);
+               fmt = "SCHED_%s not supported\n";
+       printf(fmt, policy_name(pol), min, max);
 }
 
 #define OPT_m (1<<0)
@@ -112,11 +116,11 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
                bb_show_usage();
        if (opt & OPT_p) {
                pid_str = *argv++;
-               if (*argv) { /* "-p <priority> <pid> [...]" */
+               if (*argv) { /* "-p PRIO PID [...]" */
                        priority = pid_str;
                        pid_str = *argv;
                }
-               /* else "-p <pid>", and *argv == NULL */
+               /* else "-p PID", and *argv == NULL */
                pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1);
        } else {
                priority = *argv++;
@@ -130,16 +134,18 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
  print_rt_info:
                pol = sched_getscheduler(pid);
                if (pol < 0)
-                       bb_perror_msg_and_die("can't %cet pid %d's policy", 'g', (int)pid);
-               printf("pid %d's %s scheduling policy: %s\n",
-                               pid, current_new, policies[pol].name);
+                       bb_perror_msg_and_die("can't %cet pid %u's policy", 'g', (int)pid);
+               printf("pid %u's %s scheduling policy: SCHED_%s\n",
+                       pid, current_new, policy_name(pol)
+               );
                if (sched_getparam(pid, &sp))
-                       bb_perror_msg_and_die("can't get pid %d's attributes", (int)pid);
-               printf("pid %d's %s scheduling priority: %d\n",
-                               (int)pid, current_new, sp.sched_priority);
+                       bb_perror_msg_and_die("can't get pid %u's attributes", (int)pid);
+               printf("pid %u's %s scheduling priority: %d\n",
+                       (int)pid, current_new, sp.sched_priority
+               );
                if (!*argv) {
-                       /* Either it was just "-p <pid>",
-                        * or it was "-p <priority> <pid>" and we came here
+                       /* Either it was just "-p PID",
+                        * or it was "-p PRIO PID" and we came here
                         * for the second time (see goto below) */
                        return EXIT_SUCCESS;
                }
@@ -152,9 +158,9 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
        );
 
        if (sched_setscheduler(pid, policy, &sp) < 0)
-               bb_perror_msg_and_die("can't %cet pid %d's policy", 's', (int)pid);
+               bb_perror_msg_and_die("can't %cet pid %u's policy", 's', (int)pid);
 
-       if (!argv[0]) /* "-p <priority> <pid> [...]" */
+       if (!argv[0]) /* "-p PRIO PID [...]" */
                goto print_rt_info;
 
        BB_EXECVP_or_die(argv);