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

systemd / systemd / 20447389715

21 Dec 2025 07:31PM UTC coverage: 72.37% (-0.1%) from 72.5%
20447389715

push

github

DaanDeMeyer
mkosi: Use initrd as exitrd

Let's speed up image builds by avoiding building
an exitrd and instead reusing the initrd image for
the same purpose.

308584 of 426400 relevant lines covered (72.37%)

1134231.7 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) {
78,140,826✔
23
        if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
78,140,826✔
24
                return;
25

26
        errno = *saved_errno;
78,138,035✔
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,833,928✔
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,833,928✔
54
        return -errno;
2,833,928✔
55
}
56

57
static inline int RET_NERRNO(int ret) {
40,973,605✔
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,973,605✔
75
                return negative_errno();
2,833,863✔
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,823✔
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,823✔
96
                return -errno;
41✔
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,167,604✔
111
        return IN_SET(r,
4,167,338✔
112
                      -EAGAIN,
113
                      -EINTR);
114
}
115
_DEFINE_ABS_WRAPPER(TRANSIENT);
6,307✔
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) {
729,893✔
125
        return IN_SET(r,
729,893✔
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,950✔
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,337✔
155
        return IN_SET(r,
1,337✔
156
                      -EMFILE,
157
                      -ENFILE,
158
                      -ENOMEM);
159
}
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,560✔
164
        return IN_SET(r,
186,217✔
165
                      -EOPNOTSUPP,
166
                      -ENOTTY,
167
                      -ENOSYS,
168
                      -EAFNOSUPPORT,
169
                      -EPFNOSUPPORT,
170
                      -EPROTONOSUPPORT,
171
                      -ESOCKTNOSUPPORT,
172
                      -ENOPROTOOPT);
173
}
174
_DEFINE_ABS_WRAPPER(NOT_SUPPORTED);
20,193✔
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,713✔
178
        return ERRNO_IS_NEG_NOT_SUPPORTED(r) || r == -EINVAL;
199,713✔
179
}
180
_DEFINE_ABS_WRAPPER(IOCTL_NOT_SUPPORTED);
198,218✔
181

182
/* Two different errors for access problems */
183
static inline bool ERRNO_IS_NEG_PRIVILEGE(intmax_t r) {
676,221✔
184
        return IN_SET(r,
672,858✔
185
                      -EACCES,
186
                      -EPERM);
187
}
188
_DEFINE_ABS_WRAPPER(PRIVILEGE);
3,426✔
189

190
/* Three different errors for writing on a filesystem */
191
static inline bool ERRNO_IS_NEG_FS_WRITE_REFUSED(intmax_t r) {
1,045✔
192
        return r == -EROFS || ERRNO_IS_NEG_PRIVILEGE(r);
5,715✔
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,068,621✔
207
        return IN_SET(r,
1,068,836✔
208
                      -ENODEV,
209
                      -ENXIO,
210
                      -ENOENT);
211
}
212
_DEFINE_ABS_WRAPPER(DEVICE_ABSENT);
49✔
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) {
83,693✔
216
        return ERRNO_IS_NEG_DEVICE_ABSENT(r) ||
83,693✔
217
                r == -ENOMEDIUM;
218
}
219
_DEFINE_ABS_WRAPPER(DEVICE_ABSENT_OR_EMPTY);
83,389✔
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,637✔
224
        return r == -ENODATA ||
54,637✔
225
                ERRNO_IS_NEG_NOT_SUPPORTED(r);
54,637✔
226
}
227
_DEFINE_ABS_WRAPPER(XATTR_ABSENT);
43,789✔
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