aboutsummaryrefslogtreecommitdiff
path: root/setgov.c
blob: 6e824df2c6e383fbafe05bae6de81658d92c46c1 (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
78
79
80
81
82
83
84
// SPDX-License-Identifier: BSD-2-Clause

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <glob.h>

// keep this sorted
const char *acceptable_governors[] = {
	"conservative",
	"ondemand",
	"performance",
	"powersave",
	"schedutil",
	"userspace",
};

int
elemcmp(const void *a, const void *b)
{
	return strcmp((char *)a, *(const char **)b);
}

int
main(int argc, char **argv)
{
	if (argc != 2) {
		dprintf(2, "%s: missing governor argument\n", argv[0]);
		return 1;
	}

	if (bsearch(
		argv[1],
		acceptable_governors,
		sizeof(acceptable_governors)/sizeof(*acceptable_governors),
		sizeof(*acceptable_governors),
		elemcmp
	) == NULL) {
		dprintf(2, "%s: invalid governor\n", argv[0]);
		return 5;
	}

	glob_t pglob;
	int err;
	if (!(err = glob("/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor", GLOB_NOESCAPE | GLOB_ERR, NULL, &pglob))) {
		switch (err) {
		case GLOB_NOSPACE:
			dprintf(2, "%s: out of memory\n", argv[0]);
			return 2;
		case GLOB_ABORTED:
			dprintf(2, "%s: read error\n", argv[0]);
			return 3;
		case GLOB_NOMATCH:
			dprintf(2, "%s: no cpus with scaling\n", argv[0]);
			return 4;
		}
	};

	for (size_t i = 0; i < pglob.gl_pathc; ++i) {
		int fd = open(pglob.gl_pathv[i], O_WRONLY);
		if (fd == -1) {
			dprintf(2, "%s: can't open %s\n", argv[0], pglob.gl_pathv[i]);
			return 6;
		}
		ssize_t wl = (write(fd, argv[1], strlen(argv[1]) + 1));
		if (wl == -1) {
			dprintf(2, "%s: can't write to %s\n", argv[0], pglob.gl_pathv[i]);
			return 7;
		} else if (wl == strlen(argv[1] + 1)) {
		} else {
			dprintf(2, "%s: incomplete write to %s\n", argv[0], pglob.gl_pathv[i]);
			return 8;
		}
		if (close(fd) == -1) {
			dprintf(2, "%s: can't close %s\n", argv[0], pglob.gl_pathv[i]);
			return 9;
		}
	}
	globfree(&pglob);

	return 0;
}