14#include <sys/signalfd.h>
17#include <sys/syscall.h>
20static sigset_t one_signal(
int signal) {
23 sigaddset(&set, signal);
26static int queued(
int signal, uintptr_t value) {
27 return sigqueue(getpid(), signal, (
union sigval){.sival_ptr = (
void*)value});
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);
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);
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);
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));
123 for (
int n = 0; n < 2; ++n)
126 if (area != MAP_FAILED)
127 munmap(area, page * 2);
131static void* producer(
void* ignored) {
134 return (
void*)(intptr_t)queued(SIGRTMIN, 301);
136static int readiness(
void) {
137 int failed = 0, fd = -1, epoll = -1, active = 0;
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);
149 CHECK(epoll_wait(epoll, &ready, 1, 2000) == 1 && ready.data.u64 == 0x1234 &&
150 (ready.events & EPOLLIN));
151 CHECK(pthread_join(thread, &result) == 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);
170 pthread_join(thread, NULL);
179 int fd, epoll, error;
181 volatile int ready, send, finish;
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(®istrar->ready, 1, __ATOMIC_RELEASE);
192 if (registrar->error || ed_wait(®istrar->send, 3000))
195 if (pthread_kill(registrar->waiter, SIGRTMIN) || ed_wait(®istrar->finish, 3000))
199static int epoll_waiter_lifetime(
void) {
200 int failed = 0, active = 0;
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, ®istrar) == 0);
208 CHECK(ed_wait(®istrar.ready, 1000) == 0 && registrar.error == 0);
209 CHECK(epoll_wait(registrar.epoll, &ready, 1, 0) == 0);
210 __atomic_store_n(®istrar.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(®istrar.finish, 1, __ATOMIC_RELEASE);
217 CHECK(pthread_join(thread, &result) == 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);
228 __atomic_store_n(®istrar.send, 1, __ATOMIC_RELEASE);
229 __atomic_store_n(®istrar.finish, 1, __ATOMIC_RELEASE);
230 pthread_join(thread, NULL);
232 if (registrar.epoll >= 0)
233 close(registrar.epoll);
234 if (registrar.fd >= 0)
239static int inherited_epoll(
void) {
240 int failed = 0, fd = -1, epoll = -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);
249 if (queued(SIGRTMIN, 350) || epoll_wait(epoll, &ready, 1, 0) != 0)
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)
259 int status = ed_reap(child, 3000);
261 CHECK(status == 0 && epoll_wait(epoll, &ready, 1, 0) == 0);
262 CHECK(read(fd, &record, 128) == -1 && errno == EAGAIN);
265 kill(child, SIGKILL);
266 ed_reap(child, 1000);
277 volatile int ready, go;
281 __atomic_store_n(&target->ready, 1, __ATOMIC_RELEASE);
282 if (ed_wait(&target->go, 2000))
284 return ed_read_thread(&target->reader);
286static int caller_and_sharing(
void) {
287 int failed = 0, fd = -1, alias = -1, sockets[2] = {-1, -1}, active = 0;
290 sigset_t set = one_signal(SIGRTMIN);
291 struct signalfd_siginfo record;
293 CHECK((fd = signalfd(-1, &set, SFD_NONBLOCK)) >= 0);
294 target.reader.fd = fd;
295 CHECK(pthread_create(&thread, NULL,
private_reader, &target) == 0);
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);
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);
311 int received = ed_receive_fd(sockets[1]);
312 if (received < 0 || !(fcntl(received, F_GETFD) & FD_CLOEXEC))
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())
323 CHECK(ed_send_fd(sockets[0], fd) == 0);
324 int status = ed_reap(child, 3000);
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);
335 __atomic_store_n(&target.go, 1, __ATOMIC_RELEASE);
336 pthread_join(thread, NULL);
339 kill(child, SIGKILL);
340 ed_reap(child, 1000);
346 for (
int n = 0; n < 2; ++n)
352static int source_metadata(
void) {
353 int failed = 0, fd = -1, live = 0;
356 sigset_t set = one_signal(SIGCHLD);
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) {
365 sigaddset(&set, SIGRTMAX);
366 CHECK((fd = signalfd(-1, &set, SFD_NONBLOCK)) >= 0);
367 CHECK((child = fork()) >= 0);
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);
377 CHECK(timer_create(CLOCK_MONOTONIC, &event, &timer) == 0);
379 CHECK(timer_settime(timer, 0, &setting, NULL) == 0);
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);
389 kill(child, SIGKILL);
390 ed_reap(child, 1000);
397int event_descriptor_signalfd_exec(
int argc,
char** argv) {
400 int keep = atoi(argv[2]), drop = atoi(argv[3]);
401 struct signalfd_siginfo record;
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)
411static int closing_and_exec(
void) {
412 int failed = 0, fd = -1, active = 0;
415 sigset_t set = one_signal(SIGRTMIN);
417 CHECK((fd = signalfd(-1, &set, 0)) >= 0);
419 CHECK(pthread_create(&thread, NULL, ed_read_thread, &
reader) == 0);
421 CHECK(ed_wait(&
reader.started, 1000) == 0);
423 CHECK(!__atomic_load_n(&
reader.done, __ATOMIC_ACQUIRE));
424 CHECK(close(fd) == 0);
426 CHECK(ed_wait(&
reader.done, 2000) == 0 && pthread_join(thread, NULL) == 0);
429 CHECK((child = fork()) >= 0);
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))
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);
441 int status = ed_reap(child, 4000);
448 pthread_cancel(thread);
449 pthread_join(thread, NULL);
452 kill(child, SIGKILL);
453 ed_reap(child, 1000);
458int event_descriptor_test_signalfd(
void) {
459 sigset_t set = one_signal(SIGUSR1), original;
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))
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) {
471 if (pthread_sigmask(SIG_SETMASK, &original, NULL))