1 /* $OpenBSD: util.c,v 1.1 2020/09/16 14:02:23 mpi Exp $ */ 2 3 /* 4 * Copyright (c) 2018 Visa Hankala 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/socket.h> 20 #include <sys/wait.h> 21 #include <assert.h> 22 #include <errno.h> 23 #include <poll.h> 24 #include <signal.h> 25 #include <stdio.h> 26 #include <string.h> 27 #include <unistd.h> 28 29 #include "common.h" 30 31 static void 32 signal_handler(int signum) 33 { 34 } 35 36 void 37 expect_signal_impl(int signum, const char *signame, const char *file, int line) 38 { 39 sigset_t sigmask; 40 struct timespec tmo; 41 int ret; 42 43 tmo.tv_sec = 5; 44 tmo.tv_nsec = 0; 45 sigprocmask(0, NULL, &sigmask); 46 sigdelset(&sigmask, signum); 47 ret = ppoll(NULL, 0, &tmo, &sigmask); 48 if (ret == 0) { 49 fprintf(stderr, "%s:%d: signal %s timeout\n", 50 file, line, signame); 51 _exit(1); 52 } 53 if (ret != -1) { 54 fprintf(stderr, "%s: poll: unexpected return value: %d\n", 55 __func__, ret); 56 _exit(1); 57 } 58 } 59 60 void 61 reject_signal_impl(int signum, const char *signame, const char *file, int line) 62 { 63 sigset_t sigmask; 64 65 if (sigpending(&sigmask) != 0) { 66 fprintf(stderr, "%s: sigpending: %s\n", __func__, 67 strerror(errno)); 68 _exit(1); 69 } 70 if (sigismember(&sigmask, signum)) { 71 fprintf(stderr, "%s:%d: signal %s not expected\n", file, line, 72 signame); 73 _exit(1); 74 } 75 } 76 77 void 78 test_init(void) 79 { 80 sigset_t mask; 81 82 sigemptyset(&mask); 83 sigaddset(&mask, SIGCHLD); 84 sigaddset(&mask, SIGIO); 85 sigaddset(&mask, SIGURG); 86 sigprocmask(SIG_BLOCK, &mask, NULL); 87 signal(SIGCHLD, signal_handler); 88 signal(SIGIO, signal_handler); 89 signal(SIGURG, signal_handler); 90 91 alarm(10); 92 } 93 94 void 95 test_barrier(int sfd) 96 { 97 char b = 0; 98 99 assert(write(sfd, &b, 1) == 1); 100 assert(read(sfd, &b, 1) == 1); 101 } 102 103 int 104 test_fork(pid_t *ppid, int *psfd) 105 { 106 pid_t pid; 107 int fds[2]; 108 109 assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); 110 111 pid = fork(); 112 assert(pid != -1); 113 *ppid = pid; 114 if (pid == 0) { 115 close(fds[0]); 116 *psfd = fds[1]; 117 return CHILD; 118 } else { 119 close(fds[1]); 120 *psfd = fds[0]; 121 return PARENT; 122 } 123 } 124 125 int 126 test_wait(pid_t pid, int sfd) 127 { 128 int status; 129 130 close(sfd); 131 if (pid == 0) 132 _exit(0); 133 assert(waitpid(pid, &status, 0) == pid); 134 return 0; 135 } 136