Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/filesystems/eventfd/eventfd_test.c
26305 views
1
// SPDX-License-Identifier: GPL-2.0
2
3
#define _GNU_SOURCE
4
#include <errno.h>
5
#include <fcntl.h>
6
#include <asm/unistd.h>
7
#include <linux/time_types.h>
8
#include <unistd.h>
9
#include <assert.h>
10
#include <signal.h>
11
#include <pthread.h>
12
#include <sys/epoll.h>
13
#include <sys/eventfd.h>
14
#include "../../kselftest_harness.h"
15
16
#define EVENTFD_TEST_ITERATIONS 100000UL
17
18
struct error {
19
int code;
20
char msg[512];
21
};
22
23
static int error_set(struct error *err, int code, const char *fmt, ...)
24
{
25
va_list args;
26
int r;
27
28
if (code == 0 || !err || err->code != 0)
29
return code;
30
31
err->code = code;
32
va_start(args, fmt);
33
r = vsnprintf(err->msg, sizeof(err->msg), fmt, args);
34
assert((size_t)r < sizeof(err->msg));
35
va_end(args);
36
37
return code;
38
}
39
40
static inline int sys_eventfd2(unsigned int count, int flags)
41
{
42
return syscall(__NR_eventfd2, count, flags);
43
}
44
45
TEST(eventfd_check_flag_rdwr)
46
{
47
int fd, flags;
48
49
fd = sys_eventfd2(0, 0);
50
ASSERT_GE(fd, 0);
51
52
flags = fcntl(fd, F_GETFL);
53
// The kernel automatically adds the O_RDWR flag.
54
EXPECT_EQ(flags, O_RDWR);
55
56
close(fd);
57
}
58
59
TEST(eventfd_check_flag_cloexec)
60
{
61
int fd, flags;
62
63
fd = sys_eventfd2(0, EFD_CLOEXEC);
64
ASSERT_GE(fd, 0);
65
66
flags = fcntl(fd, F_GETFD);
67
ASSERT_GT(flags, -1);
68
EXPECT_EQ(flags, FD_CLOEXEC);
69
70
close(fd);
71
}
72
73
TEST(eventfd_check_flag_nonblock)
74
{
75
int fd, flags;
76
77
fd = sys_eventfd2(0, EFD_NONBLOCK);
78
ASSERT_GE(fd, 0);
79
80
flags = fcntl(fd, F_GETFL);
81
ASSERT_GT(flags, -1);
82
EXPECT_EQ(flags & EFD_NONBLOCK, EFD_NONBLOCK);
83
EXPECT_EQ(flags & O_RDWR, O_RDWR);
84
85
close(fd);
86
}
87
88
TEST(eventfd_check_flag_cloexec_and_nonblock)
89
{
90
int fd, flags;
91
92
fd = sys_eventfd2(0, EFD_CLOEXEC|EFD_NONBLOCK);
93
ASSERT_GE(fd, 0);
94
95
flags = fcntl(fd, F_GETFL);
96
ASSERT_GT(flags, -1);
97
EXPECT_EQ(flags & EFD_NONBLOCK, EFD_NONBLOCK);
98
EXPECT_EQ(flags & O_RDWR, O_RDWR);
99
100
flags = fcntl(fd, F_GETFD);
101
ASSERT_GT(flags, -1);
102
EXPECT_EQ(flags, FD_CLOEXEC);
103
104
close(fd);
105
}
106
107
static inline void trim_newline(char *str)
108
{
109
char *pos = strrchr(str, '\n');
110
111
if (pos)
112
*pos = '\0';
113
}
114
115
static int verify_fdinfo(int fd, struct error *err, const char *prefix,
116
size_t prefix_len, const char *expect, ...)
117
{
118
char buffer[512] = {0, };
119
char path[512] = {0, };
120
va_list args;
121
FILE *f;
122
char *line = NULL;
123
size_t n = 0;
124
int found = 0;
125
int r;
126
127
va_start(args, expect);
128
r = vsnprintf(buffer, sizeof(buffer), expect, args);
129
assert((size_t)r < sizeof(buffer));
130
va_end(args);
131
132
snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", fd);
133
f = fopen(path, "re");
134
if (!f)
135
return error_set(err, -1, "fdinfo open failed for %d", fd);
136
137
while (getline(&line, &n, f) != -1) {
138
char *val;
139
140
if (strncmp(line, prefix, prefix_len))
141
continue;
142
143
found = 1;
144
145
val = line + prefix_len;
146
r = strcmp(val, buffer);
147
if (r != 0) {
148
trim_newline(line);
149
trim_newline(buffer);
150
error_set(err, -1, "%s '%s' != '%s'",
151
prefix, val, buffer);
152
}
153
break;
154
}
155
156
free(line);
157
fclose(f);
158
159
if (found == 0)
160
return error_set(err, -1, "%s not found for fd %d",
161
prefix, fd);
162
163
return 0;
164
}
165
166
TEST(eventfd_check_flag_semaphore)
167
{
168
struct error err = {0};
169
int fd, ret;
170
171
fd = sys_eventfd2(0, EFD_SEMAPHORE);
172
ASSERT_GE(fd, 0);
173
174
ret = fcntl(fd, F_GETFL);
175
ASSERT_GT(ret, -1);
176
EXPECT_EQ(ret & O_RDWR, O_RDWR);
177
178
// The semaphore could only be obtained from fdinfo.
179
ret = verify_fdinfo(fd, &err, "eventfd-semaphore: ", 19, "1\n");
180
if (ret != 0)
181
ksft_print_msg("eventfd semaphore flag check failed: %s\n", err.msg);
182
EXPECT_EQ(ret, 0);
183
184
close(fd);
185
}
186
187
/*
188
* A write(2) fails with the error EINVAL if the size of the supplied buffer
189
* is less than 8 bytes, or if an attempt is made to write the value
190
* 0xffffffffffffffff.
191
*/
192
TEST(eventfd_check_write)
193
{
194
uint64_t value = 1;
195
ssize_t size;
196
int fd;
197
198
fd = sys_eventfd2(0, 0);
199
ASSERT_GE(fd, 0);
200
201
size = write(fd, &value, sizeof(int));
202
EXPECT_EQ(size, -1);
203
EXPECT_EQ(errno, EINVAL);
204
205
size = write(fd, &value, sizeof(value));
206
EXPECT_EQ(size, sizeof(value));
207
208
value = (uint64_t)-1;
209
size = write(fd, &value, sizeof(value));
210
EXPECT_EQ(size, -1);
211
EXPECT_EQ(errno, EINVAL);
212
213
close(fd);
214
}
215
216
/*
217
* A read(2) fails with the error EINVAL if the size of the supplied buffer is
218
* less than 8 bytes.
219
*/
220
TEST(eventfd_check_read)
221
{
222
uint64_t value;
223
ssize_t size;
224
int fd;
225
226
fd = sys_eventfd2(1, 0);
227
ASSERT_GE(fd, 0);
228
229
size = read(fd, &value, sizeof(int));
230
EXPECT_EQ(size, -1);
231
EXPECT_EQ(errno, EINVAL);
232
233
size = read(fd, &value, sizeof(value));
234
EXPECT_EQ(size, sizeof(value));
235
EXPECT_EQ(value, 1);
236
237
close(fd);
238
}
239
240
241
/*
242
* If EFD_SEMAPHORE was not specified and the eventfd counter has a nonzero
243
* value, then a read(2) returns 8 bytes containing that value, and the
244
* counter's value is reset to zero.
245
* If the eventfd counter is zero at the time of the call to read(2), then the
246
* call fails with the error EAGAIN if the file descriptor has been made nonblocking.
247
*/
248
TEST(eventfd_check_read_with_nonsemaphore)
249
{
250
uint64_t value;
251
ssize_t size;
252
int fd;
253
int i;
254
255
fd = sys_eventfd2(0, EFD_NONBLOCK);
256
ASSERT_GE(fd, 0);
257
258
value = 1;
259
for (i = 0; i < EVENTFD_TEST_ITERATIONS; i++) {
260
size = write(fd, &value, sizeof(value));
261
EXPECT_EQ(size, sizeof(value));
262
}
263
264
size = read(fd, &value, sizeof(value));
265
EXPECT_EQ(size, sizeof(uint64_t));
266
EXPECT_EQ(value, EVENTFD_TEST_ITERATIONS);
267
268
size = read(fd, &value, sizeof(value));
269
EXPECT_EQ(size, -1);
270
EXPECT_EQ(errno, EAGAIN);
271
272
close(fd);
273
}
274
275
/*
276
* If EFD_SEMAPHORE was specified and the eventfd counter has a nonzero value,
277
* then a read(2) returns 8 bytes containing the value 1, and the counter's
278
* value is decremented by 1.
279
* If the eventfd counter is zero at the time of the call to read(2), then the
280
* call fails with the error EAGAIN if the file descriptor has been made nonblocking.
281
*/
282
TEST(eventfd_check_read_with_semaphore)
283
{
284
uint64_t value;
285
ssize_t size;
286
int fd;
287
int i;
288
289
fd = sys_eventfd2(0, EFD_SEMAPHORE|EFD_NONBLOCK);
290
ASSERT_GE(fd, 0);
291
292
value = 1;
293
for (i = 0; i < EVENTFD_TEST_ITERATIONS; i++) {
294
size = write(fd, &value, sizeof(value));
295
EXPECT_EQ(size, sizeof(value));
296
}
297
298
for (i = 0; i < EVENTFD_TEST_ITERATIONS; i++) {
299
size = read(fd, &value, sizeof(value));
300
EXPECT_EQ(size, sizeof(value));
301
EXPECT_EQ(value, 1);
302
}
303
304
size = read(fd, &value, sizeof(value));
305
EXPECT_EQ(size, -1);
306
EXPECT_EQ(errno, EAGAIN);
307
308
close(fd);
309
}
310
311
TEST_HARNESS_MAIN
312
313