Line | Count | Source (jump to first uncovered line) |
1 | | /* Utility functions for reading sysfs values */ |
2 | | #define _GNU_SOURCE 1 |
3 | | #include <fcntl.h> |
4 | | #include <stdio.h> |
5 | | #include <stdlib.h> |
6 | | #include <unistd.h> |
7 | | #include <stdarg.h> |
8 | | #include <ctype.h> |
9 | | #include "numa.h" |
10 | | #include "numaint.h" |
11 | | |
12 | 142 | #define SYSFS_BLOCK 4096 |
13 | | |
14 | | hidden char *sysfs_read(char *name) |
15 | 71 | { |
16 | 71 | char *buf; |
17 | 71 | int n; |
18 | 71 | int fd; |
19 | | |
20 | 71 | buf = malloc(SYSFS_BLOCK); |
21 | 71 | if (!buf) |
22 | 0 | return NULL; |
23 | 71 | fd = open(name, O_RDONLY); |
24 | 71 | n = read(fd, buf, SYSFS_BLOCK - 1); |
25 | 71 | close(fd); |
26 | 71 | if (n <= 0) { |
27 | 48 | free(buf); |
28 | 48 | return NULL; |
29 | 48 | } |
30 | 23 | buf[n] = 0; |
31 | 23 | return buf; |
32 | 71 | } |
33 | | |
34 | | hidden int sysfs_node_read(struct bitmask *mask, char *fmt, ...) |
35 | 51 | { |
36 | 51 | int n, ret = 0; |
37 | 51 | va_list ap; |
38 | 51 | char *p, *fn, *m, *end; |
39 | 51 | int num; |
40 | | |
41 | 51 | va_start(ap, fmt); |
42 | 51 | n = vasprintf(&fn, fmt, ap); |
43 | 51 | va_end(ap); |
44 | 51 | if (n < 0) |
45 | 0 | return -1; |
46 | 51 | p = sysfs_read(fn); |
47 | 51 | free(fn); |
48 | 51 | if (!p) |
49 | 48 | return -1; |
50 | | |
51 | 3 | m = p; |
52 | 3 | do { |
53 | 3 | num = strtol(m, &end, 0); |
54 | 3 | if (m == end) { |
55 | 0 | ret = -1; |
56 | 0 | goto out; |
57 | 0 | } |
58 | 3 | if (num < 0) { |
59 | 3 | ret = -2; |
60 | 3 | goto out; |
61 | 3 | } |
62 | 0 | if (num >= numa_num_task_nodes()) { |
63 | 0 | ret = -1; |
64 | 0 | goto out; |
65 | 0 | } |
66 | 0 | numa_bitmask_setbit(mask, num); |
67 | | |
68 | | /* Continuation not supported by kernel yet. */ |
69 | 0 | m = end; |
70 | 0 | while (isspace(*m) || *m == ',') |
71 | 0 | m++; |
72 | 0 | } while (isdigit(*m)); |
73 | 3 | out: |
74 | 3 | free(p); |
75 | 3 | return ret; |
76 | 3 | } |