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

systemd / systemd / 15232239991

24 May 2025 08:01PM UTC coverage: 72.053% (-0.02%) from 72.07%
15232239991

push

github

web-flow
docs: add man pages for sd_device_enumerator_[new,ref,unref,unrefp] (#37586)

For #20929.

299160 of 415197 relevant lines covered (72.05%)

703671.29 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 <errno.h>
5
#include <inttypes.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) {
73,737,386✔
27
        if (*saved_errno < 0) /* Invalidated by UNPROTECT_ERRNO? */
73,737,386✔
28
                return;
29

30
        errno = *saved_errno;
73,730,462✔
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
#define return_with_errno(r, err)                     \
47
        do {                                          \
48
                errno = ABS(err);                     \
49
                return r;                             \
50
        } while (false)
51

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

61
static inline int RET_NERRNO(int ret) {
39,327,682✔
62

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

78
        if (ret < 0)
39,327,682✔
79
                return negative_errno();
2,772,472✔
80

81
        return ret;
82
}
83

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

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

102
        return -ABS(fallback);
103
}
104

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

113
/* For send()/recv() or read()/write(). */
114
static inline bool ERRNO_IS_NEG_TRANSIENT(intmax_t r) {
3,598,901✔
115
        return IN_SET(r,
3,598,714✔
116
                      -EAGAIN,
117
                      -EINTR);
118
}
119
_DEFINE_ABS_WRAPPER(TRANSIENT);
5,759✔
120

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

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

157
/* Resource exhaustion, could be our fault or general system trouble */
158
static inline bool ERRNO_IS_NEG_RESOURCE(intmax_t r) {
1,301✔
159
        return IN_SET(r,
1,301✔
160
                      -EMFILE,
161
                      -ENFILE,
162
                      -ENOMEM);
163
}
164
_DEFINE_ABS_WRAPPER(RESOURCE);
×
165

166
/* Seven different errors for "operation/system call/socket feature not supported" */
167
static inline bool ERRNO_IS_NEG_NOT_SUPPORTED(intmax_t r) {
302,213✔
168
        return IN_SET(r,
293,735✔
169
                      -EOPNOTSUPP,
170
                      -ENOTTY,
171
                      -ENOSYS,
172
                      -EAFNOSUPPORT,
173
                      -EPFNOSUPPORT,
174
                      -EPROTONOSUPPORT,
175
                      -ESOCKTNOSUPPORT,
176
                      -ENOPROTOOPT);
177
}
178
_DEFINE_ABS_WRAPPER(NOT_SUPPORTED);
205,940✔
179

180
/* ioctl() with unsupported command/arg might additionally return EINVAL */
181
static inline bool ERRNO_IS_NEG_IOCTL_NOT_SUPPORTED(intmax_t r) {
3,207✔
182
        return ERRNO_IS_NEG_NOT_SUPPORTED(r) || r == -EINVAL;
3,207✔
183
}
184
_DEFINE_ABS_WRAPPER(IOCTL_NOT_SUPPORTED);
3,207✔
185

186
/* Two different errors for access problems */
187
static inline bool ERRNO_IS_NEG_PRIVILEGE(intmax_t r) {
700,833✔
188
        return IN_SET(r,
697,032✔
189
                      -EACCES,
190
                      -EPERM);
191
}
192
_DEFINE_ABS_WRAPPER(PRIVILEGE);
3,869✔
193

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

203
/* Three different errors for "this device does not quite exist" */
204
static inline bool ERRNO_IS_NEG_DEVICE_ABSENT(intmax_t r) {
1,217,073✔
205
        return IN_SET(r,
1,217,073✔
206
                      -ENODEV,
207
                      -ENXIO,
208
                      -ENOENT);
209
}
210
_DEFINE_ABS_WRAPPER(DEVICE_ABSENT);
137,860✔
211

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