comment all fields
[oweals/busybox.git] / miscutils / taskset.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * taskset - retrieve or set a processes's CPU affinity
4  * Copyright (c) 2006 Bernhard Fischer
5  *
6  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
7  */
8
9 #include "busybox.h"
10 #include <sched.h>
11 #include <unistd.h>
12 #include <getopt.h> /* optind */
13
14 int taskset_main(int argc, char** argv)
15 {
16         cpu_set_t mask, new_mask;
17         pid_t pid = 0;
18         unsigned long ul;
19         const char *state = "current\0new";
20         char *p_opt = NULL, *aff = NULL;
21
22         ul = bb_getopt_ulflags(argc, argv, "+p:", &p_opt);
23 #define TASKSET_OPT_p (1)
24
25         if (ul & TASKSET_OPT_p) {
26                 if (argc == optind+1) { /* -p <aff> <pid> */
27                         aff = p_opt;
28                         p_opt = argv[optind];
29                 }
30                 argv += optind; /* me -p <arg> */
31                 pid = bb_xgetularg10_bnd(p_opt, 1, ULONG_MAX); /* -p <pid> */
32         } else
33                 aff = *++argv; /* <aff> <cmd...> */
34         if (aff) {
35 /*              to_cpuset(bb_xgetularg_bnd(aff, 16, 1, ULONG_MAX), &new_mask); */
36                 unsigned i = 0;
37                 unsigned long l = bb_xgetularg_bnd(aff, 16, 1, ULONG_MAX);
38
39                 CPU_ZERO(&new_mask);
40                 while (i < CPU_SETSIZE && l >= (1<<i)) {
41                         if ((1<<i) & l)
42                                 CPU_SET(i, &new_mask);
43                         ++i;
44                 }
45         }
46
47         if (ul & TASKSET_OPT_p) {
48 print_aff:
49                 if (sched_getaffinity(pid, sizeof (mask), &mask) < 0)
50                         bb_perror_msg_and_die("Failed to %cet pid %d's affinity", 'g', pid);
51                 bb_printf("pid %d's %s affinity mask: %x\n", /* %x .. perhaps _FANCY */
52                                 pid, state, mask);
53                 if (!*argv) /* no new affinity given or we did print already, done. */
54                         return EXIT_SUCCESS;
55         }
56
57         if (sched_setaffinity(pid, sizeof (new_mask), &new_mask))
58                 bb_perror_msg_and_die("Failed to %cet pid %d's affinity", 's', pid);
59         if (ul & TASKSET_OPT_p) {
60                 state += 8;
61                 ++argv;
62                 goto print_aff;
63         }
64         ++argv;
65         execvp(*argv, argv);
66         bb_perror_msg_and_die("%s", *argv);
67 }