poll01.c revision 0b9589f3f9c0345b29cfcf7da5a1253c708303eb
1/* 2 * 3 * Copyright (c) International Business Machines Corp., 2001 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20/* 21 * Test Name: poll01 22 * 23 * Test Description: 24 * Verify that valid open file descriptor must be provided to poll() to 25 * succeed. 26 * 27 * Expected Result: 28 * poll should return the correct values when an valid file descriptor is 29 * provided. 30 * 31 * Algorithm: 32 * Setup: 33 * Setup signal handling. 34 * Pause for SIGUSR1 if option specified. 35 * 36 * Test: 37 * Loop if the proper options are given. 38 * Execute system call 39 * Check return code, if system call failed (return=-1) 40 * Issue a FAIL message. 41 * Otherwise, 42 * Verify the Functionality of system call 43 * if successful, 44 * Issue Functionality-Pass message. 45 * Otherwise, 46 * Issue Functionality-Fail message. 47 * Cleanup: 48 * Print errno log and/or timing stats if options given 49 * 50 * Usage: <for command-line> 51 * poll01 [-c n] [-f] [-i n] [-I x] [-P x] [-t] 52 * where, -c n : Run n copies concurrently. 53 * -f : Turn off functionality Testing. 54 * -i n : Execute test n times. 55 * -I x : Execute test for x seconds. 56 * -P x : Pause for x seconds between iterations. 57 * -t : Turn on syscall timing. 58 * 59 * HISTORY 60 * 07/2001 Ported by Wayne Boyer 61 * 62 * RESTRICTIONS: 63 * None. 64 */ 65#include <unistd.h> 66#include <errno.h> 67#include <fcntl.h> 68#include <sys/wait.h> 69#include <sys/poll.h> 70 71#include "test.h" 72#include "usctest.h" 73 74#define BUF_SIZE 512 75 76char *TCID = "poll01"; 77int TST_TOTAL = 1; 78 79int fildes[2]; /* file descriptors of the pipe. */ 80struct pollfd fds[1]; /* struct. for poll() */ 81 82void setup(); /* Main setup function of test */ 83void cleanup(); /* cleanup function for the test */ 84 85int main(int ac, char **av) 86{ 87 int lc; /* loop counters */ 88 int length; /* length of character string */ 89 const char *msg; 90 pid_t cpid; /* child process id */ 91 char write_buf[] = "Testing"; /* buffer string for write */ 92 char read_buf[BUF_SIZE]; /* buffer for read-end of pipe */ 93 int status; /* exit status of child process */ 94 int rval; 95 96 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) 97 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); 98 99 setup(); 100 101 for (lc = 0; TEST_LOOPING(lc); lc++) { 102 103 tst_count = 0; 104 105 /* 106 * Call poll() with the TEST macro. 107 */ 108 TEST(poll(fds, 1, -1)); 109 110 if (TEST_RETURN == -1) { 111 tst_resm(TFAIL, "poll() failed on write, errno=%d" 112 " : %s", TEST_ERRNO, strerror(TEST_ERRNO)); 113 continue; 114 } 115 116 /* write the message to the pipe */ 117 if (write(fildes[1], write_buf, sizeof(write_buf)) 118 < sizeof(write_buf)) { 119 tst_brkm(TBROK, cleanup, "write() failed on write " 120 "to pipe, error:%d", errno); 121 } 122 123 length = sizeof(write_buf); 124 125 /* Fork child process */ 126 if ((cpid = FORK_OR_VFORK()) == -1) { 127 tst_brkm(TBROK, cleanup, "fork() failed"); 128 } 129 130 if (cpid == 0) { /* Child process */ 131 /* 132 * close writing end of pipe and read from 133 * the pipe 134 */ 135 if (close(fildes[1]) == -1) { 136 tst_brkm(TFAIL, NULL, "close() failed on write " 137 "endof pipe, errno:%d", errno); 138 exit(1); 139 } 140 141 /* 142 * Set poll() data structures to check 143 * if data is present on read 144 */ 145 fds[0].fd = fildes[0]; 146 fds[0].events = POLLIN; 147 148 /* 149 * If data are present, then read the data. If poll() 150 * and read() return expected values, then the 151 * functionality of poll() is correct. 152 */ 153 rval = (poll(fds, 1, -1)); 154 155 if (rval == -1) { 156 tst_resm(TFAIL, "poll() failed on read - " 157 "errno=%d : %s", 158 TEST_ERRNO, strerror(errno)); 159 exit(1); 160 } 161 162 /* Read data from read end of pipe */ 163 if (read(fildes[0], read_buf, sizeof(read_buf)) != 164 sizeof(write_buf)) { 165 tst_brkm(TFAIL, NULL, "read() failed - " 166 "error:%d", errno); 167 exit(1); 168 } 169 170 /* Now, do the actual comparision */ 171 if (strcmp(read_buf, write_buf)) { 172 tst_resm(TFAIL, "Data from reading pipe " 173 "are different"); 174 printf 175 (" read_buf is %s\n write_buf is %s\n length is %d\n", 176 read_buf, write_buf, length); 177 exit(1); 178 } 179 180 /* Everything is fine, exit normally */ 181 exit(0); 182 } else { /* Parent process */ 183 /* Wait for child to complete execution */ 184 wait(&status); 185 186 if (WEXITSTATUS(status) == 1) { 187 tst_resm(TFAIL, "child exited abnormally"); 188 } else { 189 tst_resm(TPASS, 190 "Functionality of poll() successful"); 191 } 192 } 193 } 194 195 cleanup(); 196 tst_exit(); 197 198} 199 200/* 201 * setup() - performs all ONE TIME setup for this test. 202 * Creat read/write pipe using pipe(). 203 * Set poll data structures to check writing to the pipe. 204 */ 205void setup(void) 206{ 207 208 tst_sig(FORK, DEF_HANDLER, cleanup); 209 210 TEST_PAUSE; 211 212 /* Creat read/write pipe */ 213 if (pipe(fildes) < 0) { 214 tst_brkm(TBROK, NULL, 215 "pipe() failed to create interprocess channel"); 216 } 217 218 /* Set poll data structures */ 219 fds[0].fd = fildes[1]; 220 fds[0].events = POLLOUT; 221} 222 223/* 224 * cleanup() - performs all ONE TIME cleanup for this test at 225 * completion or premature exit. 226 * close read end of pipe if still open. 227 */ 228void cleanup(void) 229{ 230 /* 231 * print timing stats if that option was specified. 232 * print errno log if that option was specified. 233 */ 234 TEST_CLEANUP; 235 236 /* close read end of pipe if still open */ 237 if (close(fildes[0]) < 0) { 238 tst_brkm(TFAIL, NULL, "close() failed on read-end of pipe, " 239 "errno:%d", errno); 240 } 241 242} 243