The Pedigree Project 0.1
signalfd.c
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include <poll.h>
4#include <pthread.h>
5#include <signal.h>
6#include <stdlib.h>
7#include <string.h>
8#include <unistd.h>
9
10#include "contract.h"
11#include <sys/epoll.h>
12#include <sys/ioctl.h>
13#include <sys/mman.h>
14#include <sys/signalfd.h>
15#include <sys/socket.h>
16#include <sys/stat.h>
17#include <sys/syscall.h>
18#include <sys/uio.h>
19
20static sigset_t one_signal(int signal) {
21 sigset_t set;
22 sigemptyset(&set);
23 sigaddset(&set, signal);
24 return set;
25}
26static int queued(int signal, uintptr_t value) {
27 return sigqueue(getpid(), signal, (union sigval){.sival_ptr = (void*)value});
28}
29
30static int records_and_updates(void) {
31 int failed = 0, fd = -1, alias = -1, legacy = -1, pipefd[2] = {-1, -1};
32 long page = sysconf(_SC_PAGESIZE);
33 unsigned char* area =
34 mmap(NULL, page * 2, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
35 sigset_t set = one_signal(SIGUSR1), before, after, pending;
36 struct signalfd_siginfo records[3] = {0};
37 struct stat info, shared_info;
38 char path[64], link[64];
39 const uintptr_t value = UINT64_C(0x12345678abcdef01);
40 CHECK(sizeof(records[0]) == 128 && area != MAP_FAILED);
41 CHECK(mprotect(area + page, page, PROT_NONE) == 0);
42 sigaddset(&set, SIGRTMIN);
43 sigaddset(&set, SIGRTMAX);
44 CHECK(pthread_sigmask(SIG_SETMASK, NULL, &before) == 0);
45 CHECK((fd = signalfd(-1, &set, SFD_NONBLOCK | SFD_CLOEXEC)) >= 0);
46 CHECK(pthread_sigmask(SIG_SETMASK, NULL, &after) == 0);
47 CHECK(!memcmp(&before, &after, 8));
48 CHECK((fcntl(fd, F_GETFL) & O_NONBLOCK) && (fcntl(fd, F_GETFD) & FD_CLOEXEC));
49 CHECK(fstat(fd, &info) == 0 && info.st_ino != 0 && info.st_nlink == 1 &&
50 (info.st_mode & 0777) == 0600 && info.st_size == 0);
51 CHECK(lseek(fd, 0, SEEK_SET) == 0 && lseek(fd, 123, SEEK_SET) == 0);
52 CHECK(lseek(fd, 0, 123) == -1 && errno == EINVAL);
53 snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
54 CHECK(readlink(path, link, sizeof(link)) == (ssize_t)strlen("anon_inode:[signalfd]") &&
55 !memcmp(link, "anon_inode:[signalfd]", strlen("anon_inode:[signalfd]")));
56 CHECK(write(fd, records, 128) == -1 && errno == EINVAL);
57 CHECK(signalfd(-1, &set, 0x40000000) == -1 && errno == EINVAL);
58 CHECK(syscall(SYS_signalfd4, -1, &set, 16, 0) == -1 && errno == EINVAL);
59 CHECK(syscall(SYS_signalfd, -1, &set, 0) == -1 && errno == EINVAL);
60 CHECK(signalfd(-1, (sigset_t*)(area + page), 0) == -1 && errno == EFAULT);
61 CHECK(signalfd(-2, &set, 0) == -1 && errno == EBADF);
62 CHECK(pipe(pipefd) == 0);
63 CHECK(signalfd(pipefd[0], &set, 0) == -1 && errno == EINVAL);
64 CHECK((legacy = syscall(SYS_signalfd, -1, &set, 8)) >= 0);
65 close(legacy);
66 legacy = -1;
67 CHECK(read(fd, records, sizeof(records)) == -1 && errno == EAGAIN);
68 CHECK(kill(getpid(), SIGUSR1) == 0 && kill(getpid(), SIGUSR1) == 0);
69 CHECK(queued(SIGRTMIN, value) == 0 && queued(SIGRTMIN, 102) == 0);
70 CHECK(queued(SIGRTMAX, 640) == 0);
71 CHECK(read(fd, records, 127) == -1 && errno == EINVAL);
72 CHECK(read(fd, area + page, 128) == -1 && errno == EFAULT);
73 CHECK(sigpending(&pending) == 0 && sigismember(&pending, SIGUSR1) == 1);
74 memset(records, 0xa5, sizeof(records));
75 CHECK(read(fd, records, 128 * 2 + 63) == 256);
76 CHECK(records[0].ssi_signo == SIGUSR1 && records[0].ssi_code == SI_USER &&
77 records[0].ssi_pid == (unsigned)getpid() && records[0].ssi_uid == getuid());
78 CHECK(records[1].ssi_signo == (unsigned)SIGRTMIN && records[1].ssi_code == SI_QUEUE &&
79 records[1].ssi_ptr == value && records[1].ssi_pid == (unsigned)getpid() &&
80 records[1].ssi_uid == getuid());
81 CHECK(((unsigned char*)&records[2])[0] == 0xa5);
82 CHECK((alias = dup(fd)) >= 0 && !(fcntl(alias, F_GETFD) & FD_CLOEXEC));
83 CHECK(fstat(alias, &shared_info) == 0 && shared_info.st_ino == info.st_ino);
84 set = one_signal(SIGRTMAX);
85 CHECK(signalfd(alias, &set, 0) == alias);
86 CHECK((fcntl(alias, F_GETFL) & O_NONBLOCK) && (fcntl(fd, F_GETFD) & FD_CLOEXEC));
87 CHECK(read(fd, records, sizeof(records)) == 128 && records[0].ssi_signo == SIGRTMAX &&
88 records[0].ssi_int == 640);
89 CHECK(read(fd, records, sizeof(records)) == -1 && errno == EAGAIN);
90 set = one_signal(SIGRTMIN);
91 int nonblock = 0;
92 CHECK(ioctl(alias, FIONBIO, &nonblock) == 0 && !(fcntl(fd, F_GETFL) & O_NONBLOCK));
93 CHECK(signalfd(alias, &set, SFD_CLOEXEC | SFD_NONBLOCK) == alias);
94 CHECK(!(fcntl(alias, F_GETFD) & FD_CLOEXEC) && !(fcntl(fd, F_GETFL) & O_NONBLOCK));
95 CHECK(fcntl(alias, F_SETFL, O_NONBLOCK) == 0 && (fcntl(fd, F_GETFL) & O_NONBLOCK));
96 struct iovec vectors[2] = {{records, 31}, {(unsigned char*)records + 31, 97}};
97 CHECK(readv(alias, vectors, 2) == 128 && records[0].ssi_int == 102);
98 CHECK(queued(SIGRTMIN, 201) == 0 && queued(SIGRTMIN, 202) == 0);
99 CHECK(signalfd(fd, (sigset_t*)(area + page), 0) == -1 && errno == EFAULT);
100 CHECK(read(fd, area + page - 128, 256) == 128);
101 memcpy(records, area + page - 128, 128);
102 CHECK(records[0].ssi_int == 201);
103 CHECK(read(fd, records, sizeof(records)) == 128 && records[0].ssi_int == 202);
104 CHECK(read(fd, records, sizeof(records)) == -1 && errno == EAGAIN);
105 CHECK(queued(SIGRTMIN, 203) == 0 && queued(SIGRTMIN, 204) == 0);
106 vectors[0] = (struct iovec){records, 128};
107 vectors[1] = (struct iovec){area + page, 128};
108 CHECK(readv(fd, vectors, 2) == 128 && records[0].ssi_int == 203);
109 CHECK(sigpending(&pending) == 0 && sigismember(&pending, SIGRTMIN) == 1);
110 CHECK(read(fd, records, sizeof(records)) == 128 && records[0].ssi_int == 204);
111 CHECK(read(fd, records, sizeof(records)) == -1 && errno == EAGAIN);
112 sigaddset(&set, SIGKILL);
113 sigaddset(&set, SIGSTOP);
114 CHECK(signalfd(fd, &set, 0) == fd);
115 CHECK(pthread_sigmask(SIG_SETMASK, NULL, &after) == 0 && !memcmp(&before, &after, 8));
116out:
117 if (legacy >= 0)
118 close(legacy);
119 if (alias >= 0)
120 close(alias);
121 if (fd >= 0)
122 close(fd);
123 for (int n = 0; n < 2; ++n)
124 if (pipefd[n] >= 0)
125 close(pipefd[n]);
126 if (area != MAP_FAILED)
127 munmap(area, page * 2);
128 return failed;
129}
130
131static void* producer(void* ignored) {
132 (void)ignored;
133 ed_pause(30);
134 return (void*)(intptr_t)queued(SIGRTMIN, 301);
135}
136static int readiness(void) {
137 int failed = 0, fd = -1, epoll = -1, active = 0;
138 pthread_t thread;
139 void* result;
140 sigset_t set = one_signal(SIGRTMIN);
141 struct signalfd_siginfo record;
142 struct epoll_event interest = {.events = EPOLLIN, .data.u64 = 0x1234}, ready;
143 CHECK((fd = signalfd(-1, &set, SFD_NONBLOCK)) >= 0);
144 CHECK((epoll = epoll_create1(EPOLL_CLOEXEC)) >= 0);
145 CHECK(epoll_ctl(epoll, EPOLL_CTL_ADD, fd, &interest) == 0);
146 CHECK(ed_readable(fd, 0) == 0 && epoll_wait(epoll, &ready, 1, 0) == 0);
147 CHECK(pthread_create(&thread, NULL, producer, NULL) == 0);
148 active = 1;
149 CHECK(epoll_wait(epoll, &ready, 1, 2000) == 1 && ready.data.u64 == 0x1234 &&
150 (ready.events & EPOLLIN));
151 CHECK(pthread_join(thread, &result) == 0);
152 active = 0;
153 CHECK((intptr_t)result == 0);
154 CHECK(ed_readable(fd, 0) == 1 && epoll_wait(epoll, &ready, 1, 0) == 1);
155 CHECK(read(fd, &record, sizeof(record)) == 128 && record.ssi_int == 301);
156 CHECK(ed_readable(fd, 0) == 0 && epoll_wait(epoll, &ready, 1, 0) == 0);
157 interest.events = EPOLLIN | EPOLLET;
158 CHECK(epoll_ctl(epoll, EPOLL_CTL_MOD, fd, &interest) == 0);
159 CHECK(queued(SIGRTMIN, 302) == 0 && queued(SIGRTMIN, 303) == 0);
160 CHECK(epoll_wait(epoll, &ready, 1, 1000) == 1);
161 CHECK(epoll_wait(epoll, &ready, 1, 0) == 0);
162 CHECK(read(fd, &record, sizeof(record)) == 128 && record.ssi_int == 302);
163 CHECK(ed_readable(fd, 0) == 1 && epoll_wait(epoll, &ready, 1, 0) == 0);
164 CHECK(read(fd, &record, sizeof(record)) == 128 && record.ssi_int == 303);
165 CHECK(queued(SIGRTMIN, 304) == 0);
166 CHECK(epoll_wait(epoll, &ready, 1, 1000) == 1);
167 CHECK(read(fd, &record, sizeof(record)) == 128 && record.ssi_int == 304);
168out:
169 if (active)
170 pthread_join(thread, NULL);
171 if (epoll >= 0)
172 close(epoll);
173 if (fd >= 0)
174 close(fd);
175 return failed;
176}
177
179 int fd, epoll, error;
180 pthread_t waiter;
181 volatile int ready, send, finish;
182};
183static void* epoll_registrar(void* argument) {
184 struct epoll_registrar* registrar = argument;
185 sigset_t set = one_signal(SIGRTMIN);
186 struct epoll_event interest = {.events = EPOLLIN, .data.u64 = 351};
187 registrar->fd = signalfd(-1, &set, SFD_NONBLOCK);
188 registrar->epoll = epoll_create1(0);
189 registrar->error = registrar->fd < 0 || registrar->epoll < 0 ||
190 epoll_ctl(registrar->epoll, EPOLL_CTL_ADD, registrar->fd, &interest);
191 __atomic_store_n(&registrar->ready, 1, __ATOMIC_RELEASE);
192 if (registrar->error || ed_wait(&registrar->send, 3000))
193 return (void*)1;
194 ed_pause(30);
195 if (pthread_kill(registrar->waiter, SIGRTMIN) || ed_wait(&registrar->finish, 3000))
196 return (void*)1;
197 return NULL;
198}
199static int epoll_waiter_lifetime(void) {
200 int failed = 0, active = 0;
201 pthread_t thread;
202 void* result;
203 struct epoll_registrar registrar = {.fd = -1, .epoll = -1, .waiter = pthread_self()};
204 struct epoll_event ready;
205 struct signalfd_siginfo record;
206 CHECK(pthread_create(&thread, NULL, epoll_registrar, &registrar) == 0);
207 active = 1;
208 CHECK(ed_wait(&registrar.ready, 1000) == 0 && registrar.error == 0);
209 CHECK(epoll_wait(registrar.epoll, &ready, 1, 0) == 0);
210 __atomic_store_n(&registrar.send, 1, __ATOMIC_RELEASE);
211 CHECK(epoll_wait(registrar.epoll, &ready, 1, 2000) == 1 && ready.events == EPOLLIN &&
212 ready.data.u64 == 351);
213 CHECK(read(registrar.fd, &record, 128) == 128 && record.ssi_signo == SIGRTMIN &&
214 record.ssi_code == SI_TKILL);
215 CHECK(epoll_wait(registrar.epoll, &ready, 1, 0) == 0);
216 __atomic_store_n(&registrar.finish, 1, __ATOMIC_RELEASE);
217 CHECK(pthread_join(thread, &result) == 0);
218 active = 0;
219 CHECK(result == NULL);
220 CHECK(queued(SIGRTMIN, 352) == 0);
221 CHECK(epoll_wait(registrar.epoll, &ready, 1, 2000) == 1 && ready.events == EPOLLIN &&
222 ready.data.u64 == 351);
223 CHECK(read(registrar.fd, &record, 128) == 128 && record.ssi_code == SI_QUEUE &&
224 record.ssi_int == 352);
225 CHECK(epoll_wait(registrar.epoll, &ready, 1, 0) == 0);
226out:
227 if (active) {
228 __atomic_store_n(&registrar.send, 1, __ATOMIC_RELEASE);
229 __atomic_store_n(&registrar.finish, 1, __ATOMIC_RELEASE);
230 pthread_join(thread, NULL);
231 }
232 if (registrar.epoll >= 0)
233 close(registrar.epoll);
234 if (registrar.fd >= 0)
235 close(registrar.fd);
236 return failed;
237}
238
239static int inherited_epoll(void) {
240 int failed = 0, fd = -1, epoll = -1;
241 pid_t child = -1;
242 sigset_t set = one_signal(SIGRTMIN);
243 struct signalfd_siginfo record;
244 struct epoll_event interest = {.events = EPOLLIN}, ready;
245 CHECK((fd = signalfd(-1, &set, SFD_NONBLOCK)) >= 0);
246 CHECK((epoll = epoll_create1(0)) >= 0 && epoll_ctl(epoll, EPOLL_CTL_ADD, fd, &interest) == 0);
247 CHECK((child = fork()) >= 0);
248 if (!child) {
249 if (queued(SIGRTMIN, 350) || epoll_wait(epoll, &ready, 1, 0) != 0)
250 _exit(10);
251 int own_epoll = epoll_create1(0);
252 if (own_epoll < 0 || epoll_ctl(own_epoll, EPOLL_CTL_ADD, fd, &interest) ||
253 epoll_wait(own_epoll, &ready, 1, 1000) != 1 || read(fd, &record, 128) != 128 ||
254 record.ssi_int != 350)
255 _exit(11);
256 close(own_epoll);
257 _exit(0);
258 }
259 int status = ed_reap(child, 3000);
260 child = -1;
261 CHECK(status == 0 && epoll_wait(epoll, &ready, 1, 0) == 0);
262 CHECK(read(fd, &record, 128) == -1 && errno == EAGAIN);
263out:
264 if (child > 0) {
265 kill(child, SIGKILL);
266 ed_reap(child, 1000);
267 }
268 if (epoll >= 0)
269 close(epoll);
270 if (fd >= 0)
271 close(fd);
272 return failed;
273}
274
276 struct ed_reader reader;
277 volatile int ready, go;
278};
279static void* private_reader(void* argument) {
280 struct private_reader* target = argument;
281 __atomic_store_n(&target->ready, 1, __ATOMIC_RELEASE);
282 if (ed_wait(&target->go, 2000))
283 return NULL;
284 return ed_read_thread(&target->reader);
285}
286static int caller_and_sharing(void) {
287 int failed = 0, fd = -1, alias = -1, sockets[2] = {-1, -1}, active = 0;
288 pid_t child = -1;
289 pthread_t thread;
290 sigset_t set = one_signal(SIGRTMIN);
291 struct signalfd_siginfo record;
292 struct private_reader target = {.reader = {.size = 128}};
293 CHECK((fd = signalfd(-1, &set, SFD_NONBLOCK)) >= 0);
294 target.reader.fd = fd;
295 CHECK(pthread_create(&thread, NULL, private_reader, &target) == 0);
296 active = 1;
297 CHECK(ed_wait(&target.ready, 1000) == 0 && pthread_kill(thread, SIGRTMIN) == 0);
298 CHECK(ed_readable(fd, 0) == 0 && read(fd, &record, 128) == -1 && errno == EAGAIN);
299 __atomic_store_n(&target.go, 1, __ATOMIC_RELEASE);
300 CHECK(ed_wait(&target.reader.done, 2000) == 0 && pthread_join(thread, NULL) == 0);
301 active = 0;
302 memcpy(&record, target.reader.bytes, sizeof(record));
303 CHECK(target.reader.result == 128 && record.ssi_signo == SIGRTMIN && record.ssi_code == SI_TKILL);
304 CHECK((alias = dup(fd)) >= 0 && socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) == 0);
305 CHECK(queued(SIGRTMIN, 401) == 0);
306 CHECK((child = fork()) >= 0);
307 if (!child) {
308 close(sockets[0]);
309 close(fd);
310 close(alias);
311 int received = ed_receive_fd(sockets[1]);
312 if (received < 0 || !(fcntl(received, F_GETFD) & FD_CLOEXEC))
313 _exit(10);
314 set = one_signal(SIGRTMAX);
315 if (signalfd(received, &set, 0) != received || queued(SIGRTMAX, 402) ||
316 read(received, &record, 128) != 128 || record.ssi_int != 402 ||
317 record.ssi_pid != (unsigned)getpid())
318 _exit(11);
319 close(received);
320 close(sockets[1]);
321 _exit(0);
322 }
323 CHECK(ed_send_fd(sockets[0], fd) == 0);
324 int status = ed_reap(child, 3000);
325 child = -1;
326 CHECK(status == 0);
327 CHECK(read(alias, &record, 128) == -1 && errno == EAGAIN);
328 CHECK(queued(SIGRTMAX, 403) == 0);
329 CHECK(read(fd, &record, 128) == 128 && record.ssi_int == 403);
330 set = one_signal(SIGRTMIN);
331 CHECK(signalfd(alias, &set, 0) == alias);
332 CHECK(read(fd, &record, 128) == 128 && record.ssi_int == 401);
333out:
334 if (active) {
335 __atomic_store_n(&target.go, 1, __ATOMIC_RELEASE);
336 pthread_join(thread, NULL);
337 }
338 if (child > 0) {
339 kill(child, SIGKILL);
340 ed_reap(child, 1000);
341 }
342 if (alias >= 0)
343 close(alias);
344 if (fd >= 0)
345 close(fd);
346 for (int n = 0; n < 2; ++n)
347 if (sockets[n] >= 0)
348 close(sockets[n]);
349 return failed;
350}
351
352static int source_metadata(void) {
353 int failed = 0, fd = -1, live = 0;
354 pid_t child = -1;
355 timer_t timer;
356 sigset_t set = one_signal(SIGCHLD);
357 siginfo_t discarded;
358 struct timespec zero = {0};
359 struct signalfd_siginfo record;
360 struct sigevent event = {
361 .sigev_notify = SIGEV_SIGNAL, .sigev_signo = SIGRTMAX, .sigev_value.sival_int = 501};
362 struct itimerspec setting = {.it_value = {0, 30000000}, .it_interval = {0, 30000000}};
363 while (sigtimedwait(&set, &discarded, &zero) >= 0) {
364 }
365 sigaddset(&set, SIGRTMAX);
366 CHECK((fd = signalfd(-1, &set, SFD_NONBLOCK)) >= 0);
367 CHECK((child = fork()) >= 0);
368 if (!child)
369 _exit(42);
370 CHECK(ed_readable(fd, 2000) == 1);
371 CHECK(read(fd, &record, 128) == 128 && record.ssi_signo == SIGCHLD &&
372 record.ssi_code == CLD_EXITED && record.ssi_pid == (unsigned)child &&
373 record.ssi_status == 42);
374 int status = ed_reap(child, 1000);
375 child = -1;
376 CHECK(status == 42);
377 CHECK(timer_create(CLOCK_MONOTONIC, &event, &timer) == 0);
378 live = 1;
379 CHECK(timer_settime(timer, 0, &setting, NULL) == 0);
380 ed_pause(160);
381 CHECK(read(fd, &record, 128) == 128 && record.ssi_signo == SIGRTMAX &&
382 record.ssi_code == SI_TIMER && record.ssi_int == 501 &&
383 record.ssi_tid == (uint32_t)(intptr_t)timer && record.ssi_overrun >= 1);
384 CHECK(timer_getoverrun(timer) == (int)record.ssi_overrun);
385out:
386 if (live)
387 timer_delete(timer);
388 if (child > 0) {
389 kill(child, SIGKILL);
390 ed_reap(child, 1000);
391 }
392 if (fd >= 0)
393 close(fd);
394 return failed;
395}
396
397int event_descriptor_signalfd_exec(int argc, char** argv) {
398 if (argc != 4)
399 return 2;
400 int keep = atoi(argv[2]), drop = atoi(argv[3]);
401 struct signalfd_siginfo record;
402 sigset_t blocked;
403 if (fcntl(drop, F_GETFD) != -1 || errno != EBADF || fcntl(keep, F_GETFD) < 0 ||
404 pthread_sigmask(SIG_SETMASK, NULL, &blocked) || sigismember(&blocked, SIGRTMIN) != 1 ||
405 read(keep, &record, sizeof(record)) != 128 || record.ssi_int != 601 ||
406 record.ssi_signo != SIGRTMIN || record.ssi_code != SI_QUEUE)
407 return 1;
408 close(keep);
409 return 0;
410}
411static int closing_and_exec(void) {
412 int failed = 0, fd = -1, active = 0;
413 pid_t child = -1;
414 pthread_t thread;
415 sigset_t set = one_signal(SIGRTMIN);
416 struct ed_reader reader = {.size = 128};
417 CHECK((fd = signalfd(-1, &set, 0)) >= 0);
418 reader.fd = fd;
419 CHECK(pthread_create(&thread, NULL, ed_read_thread, &reader) == 0);
420 active = 1;
421 CHECK(ed_wait(&reader.started, 1000) == 0);
422 ed_pause(30);
423 CHECK(!__atomic_load_n(&reader.done, __ATOMIC_ACQUIRE));
424 CHECK(close(fd) == 0);
425 fd = -1;
426 CHECK(ed_wait(&reader.done, 2000) == 0 && pthread_join(thread, NULL) == 0);
427 active = 0;
428 CHECK(reader.result == -1 && reader.error == EBADF);
429 CHECK((child = fork()) >= 0);
430 if (!child) {
431 int keep = signalfd(-1, &set, SFD_NONBLOCK);
432 int drop = signalfd(-1, &set, SFD_NONBLOCK | SFD_CLOEXEC);
433 char kept[24], dropped[24];
434 if (keep < 0 || drop < 0 || queued(SIGRTMIN, 601))
435 _exit(10);
436 snprintf(kept, sizeof(kept), "%d", keep);
437 snprintf(dropped, sizeof(dropped), "%d", drop);
438 execl(EVENT_DESCRIPTOR_APP, EVENT_DESCRIPTOR_APP, "signalfd-exec", kept, dropped, (char*)NULL);
439 _exit(11);
440 }
441 int status = ed_reap(child, 4000);
442 child = -1;
443 CHECK(status == 0);
444out:
445 if (fd >= 0)
446 close(fd);
447 if (active) {
448 pthread_cancel(thread);
449 pthread_join(thread, NULL);
450 }
451 if (child > 0) {
452 kill(child, SIGKILL);
453 ed_reap(child, 1000);
454 }
455 return failed;
456}
457
458int event_descriptor_test_signalfd(void) {
459 sigset_t set = one_signal(SIGUSR1), original;
460 siginfo_t ignored;
461 struct timespec zero = {0};
462 sigaddset(&set, SIGRTMIN);
463 sigaddset(&set, SIGRTMAX);
464 sigaddset(&set, SIGCHLD);
465 if (pthread_sigmask(SIG_BLOCK, &set, &original))
466 return 1;
467 int failed = records_and_updates() || readiness() || epoll_waiter_lifetime() ||
468 inherited_epoll() || caller_and_sharing() || source_metadata() || closing_and_exec();
469 while (sigtimedwait(&set, &ignored, &zero) >= 0) {
470 }
471 if (pthread_sigmask(SIG_SETMASK, &original, NULL))
472 failed = 1;
473 return failed;
474}
Definition waits.c:9