• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 14895667988

07 May 2025 08:57PM UTC coverage: 72.225% (-0.007%) from 72.232%
14895667988

push

github

yuwata
network: log_link_message_debug_errno() automatically append %m if necessary

Follow-up for d28746ef5.
Fixes CID#1609753.

0 of 1 new or added line in 1 file covered. (0.0%)

20297 existing lines in 338 files now uncovered.

297407 of 411780 relevant lines covered (72.22%)

695716.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.13
/src/basic/sysctl-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <errno.h>
4
#include <fcntl.h>
5
#include <stdio.h>
6
#include <unistd.h>
7

8
#include "af-list.h"
9
#include "alloc-util.h"
10
#include "fd-util.h"
11
#include "fileio.h"
12
#include "log.h"
13
#include "macro.h"
14
#include "parse-util.h"
15
#include "path-util.h"
16
#include "socket-util.h"
17
#include "string-util.h"
18
#include "sysctl-util.h"
19

20
char* sysctl_normalize(char *s) {
31,607✔
21
        char *n;
31,607✔
22

23
        n = strpbrk(s, "/.");
31,607✔
24

25
        /* If the first separator is a slash, the path is
26
         * assumed to be normalized and slashes remain slashes
27
         * and dots remains dots. */
28

29
        if (n && *n == '.')
31,607✔
30
                /* Dots become slashes and slashes become dots. Fun. */
31
                do {
61,080✔
32
                        if (*n == '.')
61,080✔
33
                                *n = '/';
61,078✔
34
                        else
35
                                *n = '.';
2✔
36

37
                        n = strpbrk(n + 1, "/.");
61,080✔
38
                } while (n);
61,080✔
39

40
        path_simplify(s);
31,607✔
41

42
        /* Kill the leading slash, but keep the first character of the string in the same place. */
43
        if (s[0] == '/' && s[1] != 0)
31,607✔
44
                memmove(s, s+1, strlen(s));
3,662✔
45

46
        return s;
31,607✔
47
}
48

49
static int shadow_update(Hashmap **shadow, const char *property, const char *value) {
9,838✔
50
        _cleanup_free_ char *k = NULL, *v = NULL, *cur_k = NULL, *cur_v = NULL;
9,838✔
51
        int r;
9,838✔
52

53
        assert(property);
9,838✔
54
        assert(value);
9,838✔
55

56
        if (!shadow)
9,838✔
57
                return 0;
58

59
        k = strdup(property);
4,095✔
60
        if (!k)
4,095✔
61
                return -ENOMEM;
62

63
        v = strdup(value);
4,095✔
64
        if (!v)
4,095✔
65
                return -ENOMEM;
66

67
        cur_v = hashmap_remove2(*shadow, k, (void**)&cur_k);
4,095✔
68

69
        r = hashmap_ensure_put(shadow, &path_hash_ops_free_free, k, v);
4,095✔
70
        if (r < 0) {
4,095✔
UNCOV
71
                assert(r != -EEXIST);
×
72

73
                return r;
74
        }
75

76
        TAKE_PTR(k);
77
        TAKE_PTR(v);
78

79
        return 0;
80
}
81

82
int sysctl_write_full(const char *property, const char *value, Hashmap **shadow) {
9,838✔
83
        char *p;
9,838✔
84
        int r;
9,838✔
85

86
        assert(property);
9,838✔
87
        assert(value);
9,838✔
88

89
        p = strjoina("/proc/sys/", property);
49,190✔
90

91
        path_simplify(p);
9,838✔
92
        if (!path_is_normalized(p))
9,838✔
93
                return -EINVAL;
94

95
        log_debug("Setting '%s' to '%s'", p, value);
9,838✔
96

97
        r = shadow_update(shadow, p, value);
9,838✔
98
        if (r < 0)
9,838✔
99
                return r;
100

101
        return write_string_file(p, value, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER | WRITE_STRING_FILE_SUPPRESS_REDUNDANT_VIRTUAL);
9,838✔
102
}
103

104
int sysctl_writef(const char *property, const char *format, ...) {
45✔
105
        _cleanup_free_ char *v = NULL;
45✔
106
        va_list ap;
45✔
107
        int r;
45✔
108

109
        va_start(ap, format);
45✔
110
        r = vasprintf(&v, format, ap);
45✔
111
        va_end(ap);
45✔
112

113
        if (r < 0)
45✔
114
                return -ENOMEM;
115

116
        return sysctl_write(property, v);
45✔
117
}
118

119
static const char* af_to_sysctl_dir(int af) {
105,841✔
120
        if (af == AF_MPLS)
105,841✔
121
                return "mpls";
122

123
        return af_to_ipv4_ipv6(af);
105,840✔
124
}
125

126
int sysctl_write_ip_property(int af, const char *ifname, const char *property, const char *value, Hashmap **shadow) {
4,067✔
127
        const char *p;
4,067✔
128

129
        assert(property);
4,067✔
130
        assert(value);
4,067✔
131

132
        if (!IN_SET(af, AF_INET, AF_INET6, AF_MPLS))
4,067✔
133
                return -EAFNOSUPPORT;
134

135
        if (ifname) {
4,067✔
136
                if (!ifname_valid_full(ifname, IFNAME_VALID_SPECIAL))
4,066✔
137
                        return -EINVAL;
138

139
                p = strjoina("net/", af_to_sysctl_dir(af), "/conf/", ifname, "/", property);
52,858✔
140
        } else
141
                p = strjoina("net/", af_to_sysctl_dir(af), "/", property);
9✔
142

143
        return sysctl_write_full(p, value, shadow);
4,067✔
144
}
145

146
int sysctl_write_ip_neighbor_property(int af, const char *ifname, const char *property, const char *value, Hashmap **shadow) {
30✔
147
        const char *p;
30✔
148

149
        assert(property);
30✔
150
        assert(value);
30✔
151
        assert(ifname);
30✔
152

153
        if (!IN_SET(af, AF_INET, AF_INET6))
30✔
154
                return -EAFNOSUPPORT;
155

156
        if (ifname) {
30✔
157
                if (!ifname_valid_full(ifname, IFNAME_VALID_SPECIAL))
30✔
158
                        return -EINVAL;
159
                p = strjoina("net/", af_to_ipv4_ipv6(af), "/neigh/", ifname, "/", property);
390✔
160
        } else
UNCOV
161
                p = strjoina("net/", af_to_ipv4_ipv6(af), "/neigh/default/", property);
×
162

163
        return sysctl_write_full(p, value, shadow);
30✔
164
}
165

166
int sysctl_read(const char *property, char **ret) {
101,776✔
167
        char *p;
101,776✔
168
        int r;
101,776✔
169

170
        assert(property);
101,776✔
171

172
        p = strjoina("/proc/sys/", property);
508,880✔
173

174
        path_simplify(p);
101,776✔
175
        if (!path_is_normalized(p)) /* Filter out attempts to write to /proc/sys/../../…, just in case */
101,776✔
176
                return -EINVAL;
177

178
        r = read_full_virtual_file(p, ret, NULL);
101,776✔
179
        if (r < 0)
101,776✔
180
                return r;
181
        if (ret)
101,775✔
182
                delete_trailing_chars(*ret, NEWLINE);
101,775✔
183

184
        return r;
185
}
186

187
int sysctl_read_ip_property(int af, const char *ifname, const char *property, char **ret) {
101,774✔
188
        const char *p;
101,774✔
189

190
        assert(property);
101,774✔
191

192
        if (!IN_SET(af, AF_INET, AF_INET6, AF_MPLS))
101,774✔
193
                return -EAFNOSUPPORT;
194

195
        if (ifname) {
101,774✔
196
                if (!ifname_valid_full(ifname, IFNAME_VALID_SPECIAL))
101,633✔
197
                        return -EINVAL;
198

199
                p = strjoina("net/", af_to_sysctl_dir(af), "/conf/", ifname, "/", property);
1,321,229✔
200
        } else
201
                p = strjoina("net/", af_to_sysctl_dir(af), "/", property);
1,269✔
202

203
        return sysctl_read(p, ret);
101,774✔
204
}
205

206
int sysctl_read_ip_property_int(int af, const char *ifname, const char *property, int *ret) {
140✔
207
        _cleanup_free_ char *s = NULL;
140✔
208
        int r;
140✔
209

210
        assert(ret);
140✔
211

212
        r = sysctl_read_ip_property(af, ifname, property, &s);
140✔
213
        if (r < 0)
140✔
214
                return r;
215

216
        return safe_atoi(s, ret);
140✔
217
}
218

219
int sysctl_read_ip_property_uint32(int af, const char *ifname, const char *property, uint32_t *ret) {
44✔
220
        _cleanup_free_ char *s = NULL;
44✔
221
        int r;
44✔
222

223
        assert(ret);
44✔
224

225
        r = sysctl_read_ip_property(af, ifname, property, &s);
44✔
226
        if (r < 0)
44✔
227
                return r;
228

229
        return safe_atou32(s, ret);
44✔
230
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc