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

systemd / systemd / 14013585018

22 Mar 2025 03:54PM UTC coverage: 71.951% (+0.002%) from 71.949%
14013585018

push

github

web-flow
some dbus property fixes (#36830)

4 of 4 new or added lines in 1 file covered. (100.0%)

145 existing lines in 35 files now uncovered.

296620 of 412255 relevant lines covered (71.95%)

737629.16 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 "macro.h"
9

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

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

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

25
static inline void _reset_errno_(int *saved_errno) {
90,987,946✔
26
        if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
90,987,946✔
27
                return;
28

29
        errno = *saved_errno;
90,978,945✔
30
}
31

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

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

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

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

54
static inline int RET_NERRNO(int ret) {
41,792,307✔
55

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

71
        if (ret < 0)
41,795,472✔
72
                return negative_errno();
2,751,922✔
73

74
        return ret;
75
}
76

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

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

95
        return -abs(fallback);
96
}
97

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

106
assert_cc(INT_MAX <= INTMAX_MAX);
107

108
/* For send()/recv() or read()/write(). */
109
static inline bool ERRNO_IS_NEG_TRANSIENT(intmax_t r) {
3,437,055✔
110
        return IN_SET(r,
3,451,576✔
111
                      -EAGAIN,
112
                      -EINTR);
113
}
114
_DEFINE_ABS_WRAPPER(TRANSIENT);
8,588✔
115

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

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

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

161
/* Seven different errors for "operation/system call/socket feature not supported" */
162
static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(intmax_t r) {
316,642✔
163
        return IN_SET(r,
303,915✔
164
                      -EOPNOTSUPP,
165
                      -ENOTTY,
166
                      -ENOSYS,
167
                      -EAFNOSUPPORT,
168
                      -EPFNOSUPPORT,
169
                      -EPROTONOSUPPORT,
170
                      -ESOCKTNOSUPPORT,
171
                      -ENOPROTOOPT);
172
}
173
_DEFINE_ABS_WRAPPER(NOT_SUPPORTED);
216,274✔
174

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

181
/* Two different errors for access problems */
182
static inline bool ERRNO_IS_NEG_PRIVILEGE(intmax_t r) {
842,655✔
183
        return IN_SET(r,
830,401✔
184
                      -EACCES,
185
                      -EPERM);
186
}
187
_DEFINE_ABS_WRAPPER(PRIVILEGE);
13,501✔
188

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

198
/* Three different errors for "this device does not quite exist" */
199
static inline bool ERRNO_IS_NEG_DEVICE_ABSENT(intmax_t r) {
1,280,361✔
200
        return IN_SET(r,
1,438,937✔
201
                      -ENODEV,
202
                      -ENXIO,
203
                      -ENOENT);
204
}
205
_DEFINE_ABS_WRAPPER(DEVICE_ABSENT);
123,075✔
206

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