/* * epoll_pwait_test.c ( Test suite for epoll_pwait ) * Copyright (C) 2005 Davide Libenzi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Davide Libenzi * * Build: * * gcc -o epoll_pwait_test -I$(LINUX_TREE)/include/ epoll_pwait_test.c * * Where $(LINUX_TREE) is the path to the Linux kernel source tree. * */ #include #include #include #include #include #include #include #include #define SIZEOF_SIGSET (_NSIG / 8) #define __sys_epoll_pwait(epfd, pevents, maxevents, timeout, sigmask, sigsetsize) \ _syscall6(int, epoll_pwait, int, epfd, struct epoll_event *, pevents, \ int, maxevents, int, timeout, const sigset_t *, sigmask, size_t, sigsetsize) __sys_epoll_pwait(epfd, pevents, maxevents, timeout, sigmask, sigsetsize); static void sig_handler(int sig) { } int main(int ac, char **av) { int epfd, error, status, fails = 0; pid_t cpid; sigset_t sigmask, curmask; struct epoll_event evt; struct sigaction sa; int pfds[2]; if ((epfd = epoll_create(1)) == -1) { perror("epoll_create(1)"); return 1; } if (pipe(pfds) < 0) { perror("pipe()"); return 1; } memset(&evt, 0, sizeof(evt)); evt.events = EPOLLIN; if (epoll_ctl(epfd, EPOLL_CTL_ADD, pfds[0], &evt) < 0) { perror("epoll_ctl(EPOLL_CTL_ADD)"); return 1; } fprintf(stdout, "Testing from wrong epfd type : "); if ((error = epoll_pwait(pfds[0], &evt, 1, 0, NULL, 0)) != -1) fprintf(stdout, "FAIL (%d returned instead of -1)\n", error), fails++; else if (errno != EINVAL) fprintf(stdout, "FAIL (errno is %d instead of EINVAL)\n", errno), fails++; else fprintf(stdout, "OK\n"); fprintf(stdout, "Testing from closed epfd type : "); close(17); if ((error = epoll_pwait(17, &evt, 1, 0, NULL, 0)) != -1) fprintf(stdout, "FAIL (%d returned instead of -1)\n", error), fails++; else if (errno != EBADF) fprintf(stdout, "FAIL (errno is %d instead of EBADF)\n", errno), fails++; else fprintf(stdout, "OK\n"); fprintf(stdout, "Testing numevents <= 0 : "); if ((error = epoll_pwait(epfd, &evt, 0, 0, NULL, 0)) != -1) fprintf(stdout, "FAIL (%d returned instead of -1)\n", error), fails++; else if (errno != EINVAL) fprintf(stdout, "FAIL (errno is %d instead of EINVAL)\n", errno), fails++; else fprintf(stdout, "OK\n"); fprintf(stdout, "Testing numevents too big : "); if ((error = epoll_pwait(epfd, &evt, INT_MAX, 0, NULL, 0)) != -1) fprintf(stdout, "FAIL (%d returned instead of -1)\n", error), fails++; else if (errno != EINVAL) fprintf(stdout, "FAIL (errno is %d instead of EINVAL)\n", errno), fails++; else fprintf(stdout, "OK\n"); fprintf(stdout, "Testing wrong sigmask size : "); if ((error = epoll_pwait(epfd, &evt, 1, 0, &sigmask, SIZEOF_SIGSET / 2)) != -1) fprintf(stdout, "FAIL (%d returned instead of -1)\n", error), fails++; else if (errno != EINVAL) fprintf(stdout, "FAIL (errno is %d instead of EINVAL)\n", errno), fails++; else fprintf(stdout, "OK\n"); fprintf(stdout, "Testing getevents when none available : "); if ((error = epoll_pwait(epfd, &evt, 1, 0, NULL, 0)) > 0) fprintf(stdout, "FAIL (%d returned instead of 0)\n", error), fails++; else fprintf(stdout, "OK\n"); write(pfds[1], "w", 1); fprintf(stdout, "Testing getevents when one available : "); if ((error = epoll_pwait(epfd, &evt, 1, 0, NULL, 0)) != 1) fprintf(stdout, "FAIL (%d returned instead of 1)\n", error), fails++; else { fprintf(stdout, "OK\n"); read(pfds[0], &error, 1); } memset(&sa, 0, sizeof(sa)); sa.sa_restorer = NULL; sa.sa_handler = sig_handler; sigfillset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGUSR1, &sa, NULL)) { perror("sigaction"); return 1; } if (sigprocmask(SIG_SETMASK, NULL, &curmask)) { perror("sigprocmask(SIG_SETMASK, NULL, &curmask)"); return 1; } fprintf(stdout, "Testing signal when blocked : "); sigaddset(&curmask, SIGUSR1); if ((cpid = fork()) == (pid_t) -1) { perror("fork"); return 1; } else if (cpid == 0) { usleep(200000); kill(getppid(), SIGUSR1); exit(0); } if ((error = epoll_pwait(epfd, &evt, 1, 1000, &curmask, SIZEOF_SIGSET)) != 0) fprintf(stdout, "FAIL (%d returned instead of 0 - errno = %d)\n", error, errno), fails++; else fprintf(stdout, "OK\n"); waitpid(cpid, &status, 0); fprintf(stdout, "Testing signal when non blocked : "); sigdelset(&curmask, SIGUSR1); if ((cpid = fork()) == (pid_t) -1) { perror("fork"); return 1; } else if (cpid == 0) { usleep(200000); kill(getppid(), SIGUSR1); exit(0); } if ((error = epoll_pwait(epfd, &evt, 1, 1000, &curmask, SIZEOF_SIGSET)) != -1) fprintf(stdout, "FAIL (%d returned instead of -1)\n", error), fails++; else if (errno != EINTR) fprintf(stdout, "FAIL (errno is %d instead of EINTR)\n", errno), fails++; else fprintf(stdout, "OK\n"); waitpid(cpid, &status, 0); return fails ? 2: 0; }