]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/sysctl-util.c
tree-wide: drop string.h when string-util.h or friends are included
[thirdparty/systemd.git] / src / shared / sysctl-util.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
88a60da0 2
521251d2
MG
3#include <errno.h>
4#include <fcntl.h>
3f6fd1ba 5#include <stdio.h>
521251d2 6#include <unistd.h>
88a60da0 7
521251d2 8#include "fd-util.h"
3f6fd1ba 9#include "fileio.h"
88a60da0 10#include "log.h"
a8fbdf54 11#include "macro.h"
07630cea 12#include "string-util.h"
88a60da0
KS
13#include "sysctl-util.h"
14
15char *sysctl_normalize(char *s) {
16 char *n;
17
18 n = strpbrk(s, "/.");
19 /* If the first separator is a slash, the path is
20 * assumed to be normalized and slashes remain slashes
21 * and dots remains dots. */
22 if (!n || *n == '/')
23 return s;
24
25 /* Otherwise, dots become slashes and slashes become
26 * dots. Fun. */
27 while (n) {
28 if (*n == '.')
29 *n = '/';
30 else
31 *n = '.';
32
33 n = strpbrk(n + 1, "/.");
34 }
35
36 return s;
37}
38
39int sysctl_write(const char *property, const char *value) {
0f5a8be5 40 char *p;
521251d2 41 _cleanup_close_ int fd = -1;
88a60da0 42
0f5a8be5
LP
43 assert(property);
44 assert(value);
88a60da0 45
ca64ce4a 46 log_debug("Setting '%s' to '%.*s'.", property, (int) strcspn(value, NEWLINE), value);
88a60da0 47
0f5a8be5 48 p = strjoina("/proc/sys/", property);
521251d2
MG
49 fd = open(p, O_WRONLY|O_CLOEXEC);
50 if (fd < 0)
51 return -errno;
52
53 if (!endswith(value, "\n"))
54 value = strjoina(value, "\n");
55
56 if (write(fd, value, strlen(value)) < 0)
57 return -errno;
58
59 return 0;
88a60da0
KS
60}
61
6a47f2a7
LP
62int sysctl_writef(const char *property, const char *format, ...) {
63 _cleanup_free_ char *v = NULL;
64 va_list ap;
65 int r;
66
67 va_start(ap, format);
68 r = vasprintf(&v, format, ap);
69 va_end(ap);
70
71 if (r < 0)
72 return -ENOMEM;
73
74 return sysctl_write(property, v);
75}
76
3decde02
YW
77int sysctl_write_ip_property(int af, const char *ifname, const char *property, const char *value) {
78 const char *p;
79
80 assert(IN_SET(af, AF_INET, AF_INET6));
81 assert(property);
82 assert(value);
83
84 p = strjoina("/proc/sys/net/ipv", af == AF_INET ? "4" : "6",
85 ifname ? "/conf/" : "", strempty(ifname),
86 property[0] == '/' ? "" : "/", property);
87
88 log_debug("Setting '%s' to '%s'", p, value);
89
90 return write_string_file(p, value, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER);
91}
92
88a60da0 93int sysctl_read(const char *property, char **content) {
0f5a8be5 94 char *p;
88a60da0 95
0f5a8be5
LP
96 assert(property);
97 assert(content);
88a60da0 98
0f5a8be5 99 p = strjoina("/proc/sys/", property);
88a60da0
KS
100 return read_full_file(p, content, NULL);
101}
a6b3b0aa
YW
102
103int sysctl_read_ip_property(int af, const char *ifname, const char *property, char **ret) {
104 _cleanup_free_ char *value = NULL;
105 const char *p;
106 int r;
107
108 assert(IN_SET(af, AF_INET, AF_INET6));
109 assert(property);
110
111 p = strjoina("/proc/sys/net/ipv", af == AF_INET ? "4" : "6",
112 ifname ? "/conf/" : "", strempty(ifname),
113 property[0] == '/' ? "" : "/", property);
114
115 r = read_one_line_file(p, &value);
116 if (r < 0)
117 return r;
118
119 if (ret)
120 *ret = TAKE_PTR(value);
121
122 return r;
123}