source: MondoRescue/branches/3.3/mindi-busybox/miscutils/chrt.c@ 3647

Last change on this file since 3647 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:eol-style set to native
File size: 3.7 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * chrt - manipulate real-time attributes of a process
4 * Copyright (c) 2006-2007 Bernhard Reutner-Fischer
5 *
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
7 */
8
9//usage:#define chrt_trivial_usage
10//usage: "[-prfom] [PRIO] [PID | PROG ARGS]"
11//usage:#define chrt_full_usage "\n\n"
12//usage: "Change scheduling priority and class for a process\n"
13//usage: "\n -p Operate on PID"
14//usage: "\n -r Set SCHED_RR class"
15//usage: "\n -f Set SCHED_FIFO class"
16//usage: "\n -o Set SCHED_OTHER class"
17//usage: "\n -m Show min/max priorities"
18//usage:
19//usage:#define chrt_example_usage
20//usage: "$ chrt -r 4 sleep 900; x=$!\n"
21//usage: "$ chrt -f -p 3 $x\n"
22//usage: "You need CAP_SYS_NICE privileges to set scheduling attributes of a process"
23
24#include <sched.h>
25#include "libbb.h"
26
27static const struct {
28 int policy;
29 char name[sizeof("SCHED_OTHER")];
30} policies[] = {
31 {SCHED_OTHER, "SCHED_OTHER"},
32 {SCHED_FIFO, "SCHED_FIFO"},
33 {SCHED_RR, "SCHED_RR"}
34};
35
36//TODO: add
37// -b, SCHED_BATCH
38// -i, SCHED_IDLE
39
40static void show_min_max(int pol)
41{
42 const char *fmt = "%s min/max priority\t: %u/%u\n";
43 int max, min;
44
45 max = sched_get_priority_max(pol);
46 min = sched_get_priority_min(pol);
47 if ((max|min) < 0)
48 fmt = "%s not supported\n";
49 printf(fmt, policies[pol].name, min, max);
50}
51
52#define OPT_m (1<<0)
53#define OPT_p (1<<1)
54#define OPT_r (1<<2)
55#define OPT_f (1<<3)
56#define OPT_o (1<<4)
57
58int chrt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
59int chrt_main(int argc UNUSED_PARAM, char **argv)
60{
61 pid_t pid = 0;
62 unsigned opt;
63 struct sched_param sp;
64 char *pid_str;
65 char *priority = priority; /* for compiler */
66 const char *current_new;
67 int policy = SCHED_RR;
68
69 /* only one policy accepted */
70 opt_complementary = "r--fo:f--ro:o--rf";
71 opt = getopt32(argv, "+mprfo");
72 if (opt & OPT_m) { /* print min/max and exit */
73 show_min_max(SCHED_FIFO);
74 show_min_max(SCHED_RR);
75 show_min_max(SCHED_OTHER);
76 fflush_stdout_and_exit(EXIT_SUCCESS);
77 }
78 if (opt & OPT_r)
79 policy = SCHED_RR;
80 if (opt & OPT_f)
81 policy = SCHED_FIFO;
82 if (opt & OPT_o)
83 policy = SCHED_OTHER;
84
85 argv += optind;
86 if (!argv[0])
87 bb_show_usage();
88 if (opt & OPT_p) {
89 pid_str = *argv++;
90 if (*argv) { /* "-p <priority> <pid> [...]" */
91 priority = pid_str;
92 pid_str = *argv;
93 }
94 /* else "-p <pid>", and *argv == NULL */
95 pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1);
96 } else {
97 priority = *argv++;
98 if (!*argv)
99 bb_show_usage();
100 }
101
102 current_new = "current\0new";
103 if (opt & OPT_p) {
104 int pol;
105 print_rt_info:
106 pol = sched_getscheduler(pid);
107 if (pol < 0)
108 bb_perror_msg_and_die("can't %cet pid %d's policy", 'g', (int)pid);
109 printf("pid %d's %s scheduling policy: %s\n",
110 pid, current_new, policies[pol].name);
111 if (sched_getparam(pid, &sp))
112 bb_perror_msg_and_die("can't get pid %d's attributes", (int)pid);
113 printf("pid %d's %s scheduling priority: %d\n",
114 (int)pid, current_new, sp.sched_priority);
115 if (!*argv) {
116 /* Either it was just "-p <pid>",
117 * or it was "-p <priority> <pid>" and we came here
118 * for the second time (see goto below) */
119 return EXIT_SUCCESS;
120 }
121 *argv = NULL;
122 current_new += 8;
123 }
124
125 /* from the manpage of sched_getscheduler:
126 [...] sched_priority can have a value in the range 0 to 99.
127 [...] SCHED_OTHER or SCHED_BATCH must be assigned static priority 0.
128 [...] SCHED_FIFO or SCHED_RR can have static priority in 1..99 range.
129 */
130 sp.sched_priority = xstrtou_range(priority, 0, policy != SCHED_OTHER ? 1 : 0, 99);
131
132 if (sched_setscheduler(pid, policy, &sp) < 0)
133 bb_perror_msg_and_die("can't %cet pid %d's policy", 's', (int)pid);
134
135 if (!argv[0]) /* "-p <priority> <pid> [...]" */
136 goto print_rt_info;
137
138 BB_EXECVP_or_die(argv);
139}
Note: See TracBrowser for help on using the repository browser.