1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
12 #include "path-util.h"
13 #include "string-util.h"
14 #include "sysctl-util.h"
16 char *sysctl_normalize(char *s
) {
21 /* If the first separator is a slash, the path is
22 * assumed to be normalized and slashes remain slashes
23 * and dots remains dots. */
26 /* Dots become slashes and slashes become dots. Fun. */
33 n
= strpbrk(n
+ 1, "/.");
38 /* Kill the leading slash, but keep the first character of the string in the same place. */
39 if (*s
== '/' && *(s
+1))
40 memmove(s
, s
+1, strlen(s
));
45 int sysctl_write(const char *property
, const char *value
) {
47 _cleanup_close_
int fd
= -1;
52 log_debug("Setting '%s' to '%.*s'.", property
, (int) strcspn(value
, NEWLINE
), value
);
54 p
= strjoina("/proc/sys/", property
);
55 fd
= open(p
, O_WRONLY
|O_CLOEXEC
);
59 if (!endswith(value
, "\n"))
60 value
= strjoina(value
, "\n");
62 if (write(fd
, value
, strlen(value
)) < 0)
68 int sysctl_writef(const char *property
, const char *format
, ...) {
69 _cleanup_free_
char *v
= NULL
;
74 r
= vasprintf(&v
, format
, ap
);
80 return sysctl_write(property
, v
);
83 int sysctl_write_ip_property(int af
, const char *ifname
, const char *property
, const char *value
) {
86 assert(IN_SET(af
, AF_INET
, AF_INET6
));
90 p
= strjoina("/proc/sys/net/ipv", af
== AF_INET
? "4" : "6",
91 ifname
? "/conf/" : "", strempty(ifname
),
92 property
[0] == '/' ? "" : "/", property
);
94 log_debug("Setting '%s' to '%s'", p
, value
);
96 return write_string_file(p
, value
, WRITE_STRING_FILE_VERIFY_ON_FAILURE
| WRITE_STRING_FILE_DISABLE_BUFFER
);
99 int sysctl_read(const char *property
, char **ret
) {
105 p
= strjoina("/proc/sys/", property
);
106 return read_full_virtual_file(p
, ret
, NULL
);
109 int sysctl_read_ip_property(int af
, const char *ifname
, const char *property
, char **ret
) {
110 _cleanup_free_
char *value
= NULL
;
114 assert(IN_SET(af
, AF_INET
, AF_INET6
));
117 p
= strjoina("/proc/sys/net/ipv", af
== AF_INET
? "4" : "6",
118 ifname
? "/conf/" : "", strempty(ifname
),
119 property
[0] == '/' ? "" : "/", property
);
121 r
= read_full_virtual_file(p
, &value
, NULL
);
127 *ret
= TAKE_PTR(value
);