aboutsummaryrefslogtreecommitdiffstats
path: root/coreupdown.c
blob: 1de5007afeadd61367ecd31d39e932ad6fcffdd8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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;
}