diff options
Diffstat (limited to 'coreupdown.c')
-rw-r--r-- | coreupdown.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/coreupdown.c b/coreupdown.c new file mode 100644 index 0000000..1de5007 --- /dev/null +++ b/coreupdown.c @@ -0,0 +1,77 @@ +/* See LICENSE file for copyright and license details. */ +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int +main(int argc, char *argv[]) +{ + unsigned long i, count; + const char *command, *argv0; + char path[sizeof("/sys/devices/system/cpu/cpu/online") + 3 * sizeof(i)]; + int fd, ret = 0; + + if (argc == 0) { + wrong_command: + fprintf(stderr, "usage: coreup [count]\nusage: coredown [count]\n"); + return 1; + } + + argv0 = *argv++; + argc--; + command = strrchr(argv0, '/'); + command = command ? &command[1] : argv0; + + if (!strcmp(command, "coreup")) + count = ULONG_MAX; + else if (!strcmp(command, "coredown")) + count = 1; + else + goto wrong_command; + + if (argc && !strcmp(argv[0], "--")) { + argv++; + argc--; + } + + if (argc > 1) { + usage: + fprintf(stderr, "usage: %s [count]\n", argv0); + return 1; + } + + if (argc >= 1) { + char *end; + errno = 0; + if (!isdigit(**argv)) + goto usage; + count = strtoul(*argv, &end, 10); + if (!count || errno || *end) + goto usage; + argv++; + argc--; + } + + for (i = 1; i; i++) { + sprintf(path, "/sys/devices/system/cpu/cpu%zu/online", i); + fd = open(path, O_WRONLY); + if (fd < 0) { + if (errno == ENOENT) + break; + fprintf(stderr, "%s: open %s O_WRONLY\n", argv0, path); + return 1; + } + if (write(fd, i < count ? "1\n" : "0\n", 2) < 0) { + fprintf(stderr, "%s: write %s\n", argv0, path); + ret = 1; + } + close(fd); + } + + return ret; +} |