1 /* $NetBSD: t_poll.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Matthias Scheler. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/time.h> 33 34 #include <atf-c.h> 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <paths.h> 38 #include <poll.h> 39 #include <signal.h> 40 #include <unistd.h> 41 42 ATF_TC(poll_basic); 43 ATF_TC_HEAD(poll_basic, tc) 44 { 45 atf_tc_set_md_var(tc, "timeout", "10"); 46 atf_tc_set_md_var(tc, "descr", 47 "Basis functionality test for poll(2)"); 48 } 49 50 ATF_TC_BODY(poll_basic, tc) 51 { 52 int fds[2]; 53 struct pollfd pfds[2]; 54 int ret; 55 56 ATF_REQUIRE_EQ(pipe(fds), 0); 57 58 pfds[0].fd = fds[0]; 59 pfds[0].events = POLLIN; 60 pfds[1].fd = fds[1]; 61 pfds[1].events = POLLOUT; 62 63 /* 64 * Check that we get a timeout waiting for data on the read end 65 * of our pipe. 66 */ 67 pfds[0].revents = -1; 68 pfds[1].revents = -1; 69 ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[0], 1, 1), 0, 70 "got: %d", ret); 71 ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); 72 ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); 73 74 /* Check that the write end of the pipe as reported as ready. */ 75 pfds[0].revents = -1; 76 pfds[1].revents = -1; 77 ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[1], 1, 1), 1, 78 "got: %d", ret); 79 ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); 80 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ 81 pfds[1].revents); 82 83 /* Check that only the write end of the pipe as reported as ready. */ 84 pfds[0].revents = -1; 85 pfds[1].revents = -1; 86 ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 1, 87 "got: %d", ret); 88 ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); 89 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", 90 pfds[1].revents); 91 92 /* Write data to our pipe. */ 93 ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); 94 95 /* Check that both ends of our pipe are reported as ready. */ 96 pfds[0].revents = -1; 97 pfds[1].revents = -1; 98 ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 2, 99 "got: %d", ret); 100 ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", 101 pfds[0].revents); 102 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", 103 pfds[1].revents); 104 105 ATF_REQUIRE_EQ(close(fds[0]), 0); 106 ATF_REQUIRE_EQ(close(fds[1]), 0); 107 } 108 109 ATF_TC(poll_err); 110 ATF_TC_HEAD(poll_err, tc) 111 { 112 atf_tc_set_md_var(tc, "descr", "Check errors from poll(2)"); 113 } 114 115 ATF_TC_BODY(poll_err, tc) 116 { 117 struct pollfd pfd; 118 int fd = 0; 119 120 pfd.fd = fd; 121 pfd.events = POLLIN; 122 123 errno = 0; 124 ATF_REQUIRE_ERRNO(EFAULT, poll((struct pollfd *)-1, 1, -1) == -1); 125 126 errno = 0; 127 ATF_REQUIRE_ERRNO(EINVAL, poll(&pfd, 1, -2) == -1); 128 } 129 130 ATF_TC(pollts_basic); 131 ATF_TC_HEAD(pollts_basic, tc) 132 { 133 atf_tc_set_md_var(tc, "timeout", "10"); 134 atf_tc_set_md_var(tc, "descr", 135 "Basis functionality test for pollts(2)"); 136 } 137 138 ATF_TC_BODY(pollts_basic, tc) 139 { 140 int fds[2]; 141 struct pollfd pfds[2]; 142 struct timespec timeout; 143 int ret; 144 145 ATF_REQUIRE_EQ(pipe(fds), 0); 146 147 pfds[0].fd = fds[0]; 148 pfds[0].events = POLLIN; 149 pfds[1].fd = fds[1]; 150 pfds[1].events = POLLOUT; 151 152 /* Use a timeout of 1 second. */ 153 timeout.tv_sec = 1; 154 timeout.tv_nsec = 0; 155 156 /* 157 * Check that we get a timeout waiting for data on the read end 158 * of our pipe. 159 */ 160 pfds[0].revents = -1; 161 pfds[1].revents = -1; 162 ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[0], 1, &timeout, NULL), 0, 163 "got: %d", ret); 164 ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); 165 ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents); 166 167 /* Check that the write end of the pipe as reported as ready. */ 168 pfds[0].revents = -1; 169 pfds[1].revents = -1; 170 ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[1], 1, &timeout, NULL), 1, 171 "got: %d", ret); 172 ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents); 173 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\ 174 pfds[1].revents); 175 176 /* Check that only the write end of the pipe as reported as ready. */ 177 pfds[0].revents = -1; 178 pfds[1].revents = -1; 179 ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 1, 180 "got: %d", ret); 181 ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents); 182 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", 183 pfds[1].revents); 184 185 /* Write data to our pipe. */ 186 ATF_REQUIRE_EQ(write(fds[1], "", 1), 1); 187 188 /* Check that both ends of our pipe are reported as ready. */ 189 pfds[0].revents = -1; 190 pfds[1].revents = -1; 191 ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 2, 192 "got: %d", ret); 193 ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d", 194 pfds[0].revents); 195 ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d", 196 pfds[1].revents); 197 198 ATF_REQUIRE_EQ(close(fds[0]), 0); 199 ATF_REQUIRE_EQ(close(fds[1]), 0); 200 } 201 202 ATF_TC(pollts_err); 203 ATF_TC_HEAD(pollts_err, tc) 204 { 205 atf_tc_set_md_var(tc, "descr", "Check errors from pollts(2)"); 206 } 207 208 ATF_TC_BODY(pollts_err, tc) 209 { 210 struct timespec timeout; 211 struct pollfd pfd; 212 int fd = 0; 213 214 pfd.fd = fd; 215 pfd.events = POLLIN; 216 217 timeout.tv_sec = 1; 218 timeout.tv_nsec = 0; 219 220 errno = 0; 221 ATF_REQUIRE_ERRNO(EFAULT, pollts((void *)-1, 1, &timeout, NULL) == -1); 222 223 timeout.tv_sec = -1; 224 timeout.tv_nsec = -1; 225 226 errno = 0; 227 ATF_REQUIRE_ERRNO(EINVAL, pollts(&pfd, 1, &timeout, NULL) == -1); 228 } 229 230 ATF_TC(pollts_sigmask); 231 ATF_TC_HEAD(pollts_sigmask, tc) 232 { 233 atf_tc_set_md_var(tc, "timeout", "10"); 234 atf_tc_set_md_var(tc, "descr", 235 "Check that pollts(2) restores the signal mask"); 236 } 237 238 ATF_TC_BODY(pollts_sigmask, tc) 239 { 240 int fd; 241 struct pollfd pfd; 242 struct timespec timeout; 243 sigset_t mask; 244 int ret; 245 246 /* Cf kern/44986 */ 247 248 fd = open(_PATH_DEVNULL, O_RDONLY); 249 ATF_REQUIRE(fd >= 0); 250 251 pfd.fd = fd; 252 pfd.events = POLLIN; 253 254 /* Use a timeout of 1 second. */ 255 timeout.tv_sec = 1; 256 timeout.tv_nsec = 0; 257 258 /* Unblock all signals. */ 259 ATF_REQUIRE_EQ(sigfillset(&mask), 0); 260 ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0); 261 262 /* 263 * Check that pollts(2) immediately returns. We block *all* 264 * signals during pollts(2). 265 */ 266 ATF_REQUIRE_EQ_MSG(ret = pollts(&pfd, 1, &timeout, &mask), 1, 267 "got: %d", ret); 268 269 /* Check that signals are now longer blocked. */ 270 ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0); 271 ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0, 272 "signal mask was changed."); 273 274 ATF_REQUIRE_EQ(close(fd), 0); 275 } 276 277 ATF_TP_ADD_TCS(tp) 278 { 279 280 ATF_TP_ADD_TC(tp, poll_basic); 281 ATF_TP_ADD_TC(tp, poll_err); 282 ATF_TP_ADD_TC(tp, pollts_basic); 283 ATF_TP_ADD_TC(tp, pollts_err); 284 ATF_TP_ADD_TC(tp, pollts_sigmask); 285 286 return atf_no_error(); 287 } 288