Coverage Report

Created: 2026-05-30 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/librdkafka/src/rdposix.h
Line
Count
Source
1
/*
2
 * librdkafka - Apache Kafka C library
3
 *
4
 * Copyright (c) 2012-2022, Magnus Edenhill
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright notice,
11
 *    this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright notice,
13
 *    this list of conditions and the following disclaimer in the documentation
14
 *    and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
 * POSSIBILITY OF SUCH DAMAGE.
27
 */
28
29
/**
30
 * POSIX system support
31
 */
32
#ifndef _RDPOSIX_H_
33
#define _RDPOSIX_H_
34
35
#include <unistd.h>
36
#include <stdio.h>
37
#include <sys/time.h>
38
#include <inttypes.h>
39
#include <fcntl.h>
40
#include <errno.h>
41
#include <string.h>
42
43
/**
44
 * Types
45
 */
46
47
48
/**
49
 * Annotations, attributes, optimizers
50
 */
51
#ifndef likely
52
#define likely(x) __builtin_expect((x), 1)
53
#endif
54
#ifndef unlikely
55
#define unlikely(x) __builtin_expect((x), 0)
56
#endif
57
58
#define RD_UNUSED             __attribute__((unused))
59
#define RD_INLINE             inline
60
#define RD_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
61
#define RD_NORETURN           __attribute__((noreturn))
62
#define RD_IS_CONSTANT(p)     __builtin_constant_p((p))
63
#define RD_TLS                __thread
64
65
/**
66
 * Allocation
67
 */
68
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
69
/* alloca(3) is in stdlib on FreeBSD */
70
#include <alloca.h>
71
#endif
72
73
#define rd_alloca(N) alloca(N)
74
75
76
/**
77
 * Strings, formatting, printf, ..
78
 */
79
80
/* size_t and ssize_t format strings */
81
#define PRIusz "zu"
82
#define PRIdsz "zd"
83
84
#ifndef RD_FORMAT
85
#define RD_FORMAT(...) __attribute__((format(__VA_ARGS__)))
86
#endif
87
#define rd_snprintf(...)  snprintf(__VA_ARGS__)
88
#define rd_vsnprintf(...) vsnprintf(__VA_ARGS__)
89
90
#define rd_strcasecmp(A, B)     strcasecmp(A, B)
91
#define rd_strncasecmp(A, B, N) strncasecmp(A, B, N)
92
93
94
#ifdef HAVE_STRCASESTR
95
#define rd_strcasestr(HAYSTACK, NEEDLE) strcasestr(HAYSTACK, NEEDLE)
96
#else
97
#define rd_strcasestr(HAYSTACK, NEEDLE) _rd_strcasestr(HAYSTACK, NEEDLE)
98
#endif
99
100
101
/**
102
 * Errors
103
 */
104
105
106
#define rd_set_errno(err) (errno = (err))
107
108
#if HAVE_STRERROR_R
109
static RD_INLINE RD_UNUSED const char *rd_strerror(int err) {
110
        static RD_TLS char ret[128];
111
112
#if defined(__GLIBC__) && defined(_GNU_SOURCE)
113
        return strerror_r(err, ret, sizeof(ret));
114
#else /* XSI version */
115
        int r;
116
        /* The r assignment is to catch the case where
117
         * _GNU_SOURCE is not defined but the GNU version is
118
         * picked up anyway. */
119
        r = strerror_r(err, ret, sizeof(ret));
120
        if (unlikely(r))
121
                rd_snprintf(ret, sizeof(ret), "strerror_r(%d) failed (ret %d)",
122
                            err, r);
123
        return ret;
124
#endif
125
}
126
#else
127
#define rd_strerror(err) strerror(err)
128
#endif
129
130
131
/**
132
 * Atomics
133
 */
134
#include "rdatomic.h"
135
136
/**
137
 * Misc
138
 */
139
140
/**
141
 * Microsecond sleep.
142
 * Will retry on signal interrupt unless *terminate is true.
143
 */
144
0
static RD_INLINE RD_UNUSED void rd_usleep(int usec, rd_atomic32_t *terminate) {
145
0
        struct timespec req = {usec / 1000000, (long)(usec % 1000000) * 1000};
146
0
147
0
        /* Retry until complete (issue #272), unless terminating. */
148
0
        while (nanosleep(&req, &req) == -1 &&
149
0
               (errno == EINTR && (!terminate || !rd_atomic32_get(terminate))))
150
0
                ;
151
0
}
Unexecuted instantiation: fuzz_regex.c:rd_usleep
Unexecuted instantiation: regexp.c:rd_usleep
152
153
154
155
#define rd_gettimeofday(tv, tz) gettimeofday(tv, tz)
156
157
158
#ifndef __COVERITY__
159
4.97k
#define rd_assert(EXPR) assert(EXPR)
160
#else
161
extern void __coverity_panic__(void);
162
#define rd_assert(EXPR)                                                        \
163
        do {                                                                   \
164
                if (!(EXPR))                                                   \
165
                        __coverity_panic__();                                  \
166
        } while (0)
167
#endif
168
169
170
static RD_INLINE RD_UNUSED const char *rd_getenv(const char *env,
171
0
                                                 const char *def) {
172
0
        const char *tmp;
173
0
        tmp = getenv(env);
174
0
        if (tmp && *tmp)
175
0
                return tmp;
176
0
        return def;
177
0
}
Unexecuted instantiation: fuzz_regex.c:rd_getenv
Unexecuted instantiation: regexp.c:rd_getenv
178
179
180
/**
181
 * Empty struct initializer
182
 */
183
#define RD_ZERO_INIT                                                           \
184
        {}
185
186
/**
187
 * Sockets, IO
188
 */
189
190
/** @brief Socket type */
191
typedef int rd_socket_t;
192
193
/** @brief Socket API error return value */
194
#define RD_SOCKET_ERROR (-1)
195
196
/** @brief Last socket error */
197
#define rd_socket_errno errno
198
199
200
/** @brief String representation of socket error */
201
#define rd_socket_strerror(ERR) rd_strerror(ERR)
202
203
/** @brief poll() struct type */
204
typedef struct pollfd rd_pollfd_t;
205
206
/** @brief poll(2) */
207
#define rd_socket_poll(POLLFD, FDCNT, TIMEOUT_MS)                              \
208
        poll(POLLFD, FDCNT, TIMEOUT_MS)
209
210
/**
211
 * @brief Set socket to non-blocking
212
 * @returns 0 on success or errno on failure.
213
 */
214
0
static RD_UNUSED int rd_fd_set_nonblocking(int fd) {
215
0
        int fl = fcntl(fd, F_GETFL, 0);
216
0
        if (fl == -1 || fcntl(fd, F_SETFL, fl | O_NONBLOCK) == -1)
217
0
                return errno;
218
0
        return 0;
219
0
}
Unexecuted instantiation: fuzz_regex.c:rd_fd_set_nonblocking
Unexecuted instantiation: regexp.c:rd_fd_set_nonblocking
220
221
/**
222
 * @brief Create non-blocking pipe
223
 * @returns 0 on success or errno on failure
224
 */
225
0
static RD_UNUSED int rd_pipe_nonblocking(rd_socket_t *fds) {
226
0
        if (pipe(fds) == -1 || rd_fd_set_nonblocking(fds[0]) == -1 ||
227
0
            rd_fd_set_nonblocking(fds[1]))
228
0
                return errno;
229
0
230
0
                /* Minimize buffer sizes to avoid a large number
231
0
                 * of signaling bytes to accumulate when
232
0
                 * io-signalled queue is not being served for a while. */
233
0
#ifdef F_SETPIPE_SZ
234
0
        /* Linux automatically rounds the pipe size up
235
0
         * to the minimum size. */
236
0
        fcntl(fds[0], F_SETPIPE_SZ, 100);
237
0
        fcntl(fds[1], F_SETPIPE_SZ, 100);
238
0
#endif
239
0
        return 0;
240
0
}
Unexecuted instantiation: fuzz_regex.c:rd_pipe_nonblocking
Unexecuted instantiation: regexp.c:rd_pipe_nonblocking
241
#define rd_socket_read(fd, buf, sz)  read(fd, buf, sz)
242
#define rd_socket_write(fd, buf, sz) write(fd, buf, sz)
243
#define rd_socket_close(fd)          close(fd)
244
245
/* File IO */
246
#define rd_write(fd, buf, sz)      write(fd, buf, sz)
247
#define rd_open(path, flags, mode) open(path, flags, mode)
248
#define rd_close(fd)               close(fd)
249
250
#endif /* _RDPOSIX_H_ */