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

systemd / systemd / 14805371838

02 May 2025 11:41AM UTC coverage: 72.244% (+0.001%) from 72.243%
14805371838

push

github

web-flow
Various changes to prepare for running IWYU on the repository (#37319)

These are various commits that were required to get things compiling
after running IWYU. I think all of them make sense on their own, hence
this split PR to merge them ahead of time.

81 of 96 new or added lines in 48 files covered. (84.38%)

178 existing lines in 39 files now uncovered.

297233 of 411432 relevant lines covered (72.24%)

694826.11 hits per line

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

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

4
#include <inttypes.h>
5
#include <stdlib.h>
6
#include <string.h>
7

8
#include "assert-util.h"
9
#include "macro.h"
10

11
/* strerror(3) says that glibc uses a maximum length of 1024 bytes. */
12
#define ERRNO_BUF_LEN 1024
13

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

21
/* A helper to print an error message or message for functions that return 0 on EOF.
22
 * Note that we can't use ({ … }) to define a temporary variable, so errnum is
23
 * evaluated twice. */
24
#define STRERROR_OR_EOF(errnum) ((errnum) != 0 ? STRERROR(errnum) : "Unexpected EOF")
25

26
static inline void _reset_errno_(int *saved_errno) {
71,098,555✔
27
        if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
71,098,555✔
28
                return;
29

30
        errno = *saved_errno;
71,091,393✔
31
}
32

33
#define PROTECT_ERRNO                           \
34
        _cleanup_(_reset_errno_) _unused_ int _saved_errno_ = errno
35

36
#define UNPROTECT_ERRNO                         \
37
        do {                                    \
38
                errno = _saved_errno_;          \
39
                _saved_errno_ = -1;             \
40
        } while (false)
41

42
#define LOCAL_ERRNO(value)                      \
43
        PROTECT_ERRNO;                          \
44
        errno = abs(value)
45

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

55
static inline int RET_NERRNO(int ret) {
38,386,513✔
56

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

72
        if (ret < 0)
38,386,872✔
73
                return negative_errno();
2,691,669✔
74

75
        return ret;
76
}
77

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

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

96
        return -abs(fallback);
97
}
98

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

107
assert_cc(INT_MAX <= INTMAX_MAX);
108

109
/* For send()/recv() or read()/write(). */
110
static inline bool ERRNO_IS_NEG_TRANSIENT(intmax_t r) {
3,366,610✔
111
        return IN_SET(r,
3,366,430✔
112
                      -EAGAIN,
113
                      -EINTR);
114
}
115
_DEFINE_ABS_WRAPPER(TRANSIENT);
5,896✔
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) {
553,315✔
125
        return IN_SET(r,
553,315✔
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);
2,557✔
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,299✔
155
        return IN_SET(r,
1,299✔
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) {
301,439✔
164
        return IN_SET(r,
293,014✔
165
                      -EOPNOTSUPP,
166
                      -ENOTTY,
167
                      -ENOSYS,
168
                      -EAFNOSUPPORT,
169
                      -EPFNOSUPPORT,
170
                      -EPROTONOSUPPORT,
171
                      -ESOCKTNOSUPPORT,
172
                      -ENOPROTOOPT);
173
}
174
_DEFINE_ABS_WRAPPER(NOT_SUPPORTED);
205,960✔
175

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

182
/* Two different errors for access problems */
183
static inline bool ERRNO_IS_NEG_PRIVILEGE(intmax_t r) {
684,762✔
184
        return IN_SET(r,
680,969✔
185
                      -EACCES,
186
                      -EPERM);
187
}
188
_DEFINE_ABS_WRAPPER(PRIVILEGE);
3,901✔
189

190
/* Three different errors for "not enough disk space" */
191
static inline bool ERRNO_IS_NEG_DISK_SPACE(intmax_t r) {
×
192
        return IN_SET(r,
×
193
                      -ENOSPC,
194
                      -EDQUOT,
195
                      -EFBIG);
196
}
197
_DEFINE_ABS_WRAPPER(DISK_SPACE);
×
198

199
/* Three different errors for "this device does not quite exist" */
200
static inline bool ERRNO_IS_NEG_DEVICE_ABSENT(intmax_t r) {
1,195,990✔
201
        return IN_SET(r,
1,195,990✔
202
                      -ENODEV,
203
                      -ENXIO,
204
                      -ENOENT);
205
}
206
_DEFINE_ABS_WRAPPER(DEVICE_ABSENT);
138,467✔
207

208
/* Quite often we want to handle cases where the backing FS doesn't support extended attributes at all and
209
 * where it simply doesn't have the requested xattr the same way */
210
static inline bool ERRNO_IS_NEG_XATTR_ABSENT(intmax_t r) {
41,778✔
211
        return r == -ENODATA ||
41,778✔
212
                ERRNO_IS_NEG_NOT_SUPPORTED(r);
41,778✔
213
}
214
_DEFINE_ABS_WRAPPER(XATTR_ABSENT);
31,747✔
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