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

systemd / systemd / 20561496515

28 Dec 2025 11:55AM UTC coverage: 72.478% (-0.2%) from 72.692%
20561496515

push

github

web-flow
core: several follow-ups for BindNetworkInterface= (#40202)

13 of 54 new or added lines in 5 files covered. (24.07%)

1051 existing lines in 43 files now uncovered.

309149 of 426542 relevant lines covered (72.48%)

1254687.42 hits per line

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

82.0
/src/basic/errno-util.h
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
#pragma once
3

4
#include <string.h>
5

6
#include "basic-forward.h"
7

8
/* strerror(3) says that glibc uses a maximum length of 1024 bytes. */
9
#define ERRNO_BUF_LEN           1024
10

11
/* Note: the lifetime of the compound literal is the immediately surrounding block,
12
 * see C11 §6.5.2.5, and
13
 * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks
14
 *
15
 * Note that we use the GNU variant of strerror_r() here. */
16
#define STRERROR(errnum) strerror_r(ABS(errnum), (char[ERRNO_BUF_LEN]){}, ERRNO_BUF_LEN)
17

18
/* A helper to print an error message or message for functions that return 0 on EOF. */
19
const char* strerror_or_eof(int errnum, char *buf, size_t buflen);
20
#define STRERROR_OR_EOF(errnum) strerror_or_eof(errnum, (char[ERRNO_BUF_LEN]){}, ERRNO_BUF_LEN)
21

22
static inline void _reset_errno_(int *saved_errno) {
77,516,203✔
23
        if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
77,516,203✔
24
                return;
25

26
        errno = *saved_errno;
77,513,445✔
27
}
28

29
#define PROTECT_ERRNO                           \
30
        _cleanup_(_reset_errno_) _unused_ int _saved_errno_ = errno
31

32
#define UNPROTECT_ERRNO                         \
33
        do {                                    \
34
                errno = _saved_errno_;          \
35
                _saved_errno_ = -1;             \
36
        } while (false)
37

38
#define LOCAL_ERRNO(value)                      \
39
        PROTECT_ERRNO;                          \
40
        errno = ABS(value)
41

42
#define return_with_errno(r, err)                     \
43
        do {                                          \
44
                errno = ABS(err);                     \
45
                return r;                             \
46
        } while (false)
47

48
static inline int negative_errno(void) {
2,821,080✔
49
        /* This helper should be used to shut up gcc if you know 'errno' is
50
         * negative. Instead of "return -errno;", use "return negative_errno();"
51
         * It will suppress bogus gcc warnings in case it assumes 'errno' might
52
         * be 0 and thus the caller's error-handling might not be triggered. */
53
        assert_return(errno > 0, -EINVAL);
2,821,080✔
54
        return -errno;
2,821,080✔
55
}
56

57
static inline int RET_NERRNO(int ret) {
40,361,816✔
58

59
        /* Helper to wrap system calls in to make them return negative errno errors. This brings system call
60
         * error handling in sync with how we usually handle errors in our own code, i.e. with immediate
61
         * returning of negative errno. Usage is like this:
62
         *
63
         *     …
64
         *     r = RET_NERRNO(unlink(t));
65
         *     …
66
         *
67
         * or
68
         *
69
         *     …
70
         *     fd = RET_NERRNO(open("/etc/fstab", O_RDONLY|O_CLOEXEC));
71
         *     …
72
         */
73

74
        if (ret < 0)
40,361,816✔
75
                return negative_errno();
2,821,012✔
76

77
        return ret;
78
}
79

80
/* Collect possible errors in <acc>, so that the first error can be returned.
81
 * Returns (possibly updated) <acc>. */
82
#define RET_GATHER(acc, err)                    \
83
        ({                                      \
84
                int *__a = &(acc), __e = (err); \
85
                if (*__a >= 0 && __e < 0)       \
86
                        *__a = __e;             \
87
                *__a;                           \
88
        })
89

90
static inline int errno_or_else(int fallback) {
69,798✔
91
        /* To be used when invoking library calls where errno handling is not defined clearly: we return
92
         * errno if it is set, and the specified error otherwise. The idea is that the caller initializes
93
         * errno to zero before doing an API call, and then uses this helper to retrieve a somewhat useful
94
         * error code */
95
        if (errno > 0)
69,798✔
96
                return -errno;
40✔
97

98
        return -ABS(fallback);
99
}
100

101
/* abs(3) says: Trying to take the absolute value of the most negative integer is not defined. */
102
#define _DEFINE_ABS_WRAPPER(name)                         \
103
        static inline bool ERRNO_IS_##name(intmax_t r) {  \
104
                if (r == INTMAX_MIN)                      \
105
                        return false;                     \
106
                return ERRNO_IS_NEG_##name(-ABS(r));      \
107
        }
108

109
/* For send()/recv() or read()/write(). */
110
static inline bool ERRNO_IS_NEG_TRANSIENT(intmax_t r) {
4,180,539✔
111
        return IN_SET(r,
4,180,303✔
112
                      -EAGAIN,
113
                      -EINTR);
114
}
115
_DEFINE_ABS_WRAPPER(TRANSIENT);
6,295✔
116

117
/* Hint #1: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5.
118
 *
119
 * Hint #2: The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases.  See the
120
 *          icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources.
121
 *
122
 * Hint #3: When asynchronous connect() on TCP fails because the host never acknowledges a single packet,
123
 *          kernel tells us that with ETIMEDOUT, see tcp(7). */
124
static inline bool ERRNO_IS_NEG_DISCONNECT(intmax_t r) {
728,464✔
125
        return IN_SET(r,
728,464✔
126
                      -ECONNABORTED,
127
                      -ECONNREFUSED,
128
                      -ECONNRESET,
129
                      -EHOSTDOWN,
130
                      -EHOSTUNREACH,
131
                      -ENETDOWN,
132
                      -ENETRESET,
133
                      -ENETUNREACH,
134
                      -ENONET,
135
                      -ENOPROTOOPT,
136
                      -ENOTCONN,
137
                      -EPIPE,
138
                      -EPROTO,
139
                      -ESHUTDOWN,
140
                      -ETIMEDOUT);
141
}
142
_DEFINE_ABS_WRAPPER(DISCONNECT);
3,930✔
143

144
/* Transient errors we might get on accept() that we should ignore. As per error handling comment in
145
 * the accept(2) man page. */
146
static inline bool ERRNO_IS_NEG_ACCEPT_AGAIN(intmax_t r) {
×
147
        return ERRNO_IS_NEG_DISCONNECT(r) ||
×
148
                ERRNO_IS_NEG_TRANSIENT(r) ||
×
149
                r == -EOPNOTSUPP;
150
}
151
_DEFINE_ABS_WRAPPER(ACCEPT_AGAIN);
×
152

153
/* Resource exhaustion, could be our fault or general system trouble */
154
static inline bool ERRNO_IS_NEG_RESOURCE(intmax_t r) {
1,331✔
155
        return IN_SET(r,
1,331✔
156
                      -EMFILE,
157
                      -ENFILE,
158
                      -ENOMEM);
159
}
UNCOV
160
_DEFINE_ABS_WRAPPER(RESOURCE);
×
161

162
/* Seven different errors for "operation/system call/socket feature not supported" */
163
static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(intmax_t r) {
391,663✔
164
        return IN_SET(r,
186,318✔
165
                      -EOPNOTSUPP,
166
                      -ENOTTY,
167
                      -ENOSYS,
168
                      -EAFNOSUPPORT,
169
                      -EPFNOSUPPORT,
170
                      -EPROTONOSUPPORT,
171
                      -ESOCKTNOSUPPORT,
172
                      -ENOPROTOOPT);
173
}
174
_DEFINE_ABS_WRAPPER(NOT_SUPPORTED);
20,208✔
175

176
/* ioctl() with unsupported command/arg might additionally return EINVAL */
177
static inline bool ERRNO_IS_NEG_IOCTL_NOT_SUPPORTED(intmax_t r) {
199,702✔
178
        return ERRNO_IS_NEG_NOT_SUPPORTED(r) || r == -EINVAL;
199,702✔
179
}
180
_DEFINE_ABS_WRAPPER(IOCTL_NOT_SUPPORTED);
198,207✔
181

182
/* Two different errors for access problems */
183
static inline bool ERRNO_IS_NEG_PRIVILEGE(intmax_t r) {
673,556✔
184
        return IN_SET(r,
670,194✔
185
                      -EACCES,
186
                      -EPERM);
187
}
188
_DEFINE_ABS_WRAPPER(PRIVILEGE);
3,423✔
189

190
/* Three different errors for writing on a filesystem */
191
static inline bool ERRNO_IS_NEG_FS_WRITE_REFUSED(intmax_t r) {
1,042✔
192
        return r == -EROFS || ERRNO_IS_NEG_PRIVILEGE(r);
5,721✔
193
}
194
_DEFINE_ABS_WRAPPER(FS_WRITE_REFUSED);
×
195

196
/* Three different errors for "not enough disk space" */
197
static inline bool ERRNO_IS_NEG_DISK_SPACE(intmax_t r) {
×
198
        return IN_SET(r,
×
199
                      -ENOSPC,
200
                      -EDQUOT,
201
                      -EFBIG);
202
}
203
_DEFINE_ABS_WRAPPER(DISK_SPACE);
×
204

205
/* Three different errors for "this device does not quite exist" */
206
static inline bool ERRNO_IS_NEG_DEVICE_ABSENT(intmax_t r) {
1,061,140✔
207
        return IN_SET(r,
1,061,245✔
208
                      -ENODEV,
209
                      -ENXIO,
210
                      -ENOENT);
211
}
212
_DEFINE_ABS_WRAPPER(DEVICE_ABSENT);
159✔
213

214
/* Device is absent or "empty". We get -ENOMEDIUM from CD/DVD devices, also in VMs. */
215
static inline bool ERRNO_IS_NEG_DEVICE_ABSENT_OR_EMPTY(intmax_t r) {
81,817✔
216
        return ERRNO_IS_NEG_DEVICE_ABSENT(r) ||
81,817✔
217
                r == -ENOMEDIUM;
218
}
219
_DEFINE_ABS_WRAPPER(DEVICE_ABSENT_OR_EMPTY);
81,513✔
220

221
/* Quite often we want to handle cases where the backing FS doesn't support extended attributes at all and
222
 * where it simply doesn't have the requested xattr the same way */
223
static inline bool ERRNO_IS_NEG_XATTR_ABSENT(intmax_t r) {
54,632✔
224
        return r == -ENODATA ||
54,632✔
225
                ERRNO_IS_NEG_NOT_SUPPORTED(r);
54,632✔
226
}
227
_DEFINE_ABS_WRAPPER(XATTR_ABSENT);
43,766✔
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