poll01.c revision 43337a3cf6f8809647cf9fc6c0054241f44b1fb1
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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"; /* Test program identifier. */ 77int TST_TOTAL=1; /* Total number of test cases. */ 78extern int Tst_count; /* Test Case counter for tst_* routines */ 79 80int fildes[2]; /* file descriptors of the pipe. */ 81struct pollfd fds[1]; /* struct. for poll() */ 82 83void setup(); /* Main setup function of test */ 84void cleanup(); /* cleanup function for the test */ 85 86int 87main(int ac, char **av) 88{ 89 int lc; /* loop counters */ 90 int length; /* length of character string */ 91 char *msg; /* message returned from parse_opts */ 92 pid_t cpid; /* child process id */ 93 char write_buf[] = "Testing"; /* buffer string for write */ 94 char read_buf[BUF_SIZE]; /* buffer for read-end of pipe */ 95 int status; /* exit status of child process */ 96 int rval; 97 98 /* Parse standard options given to run the test. */ 99 msg = parse_opts(ac, av, (option_t *)NULL, NULL); 100 if (msg != (char *)NULL) { 101 tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg); 102 } 103 104 /* Perform global setup for test */ 105 setup(); 106 107 108 /* Check looping state if -i option given */ 109 for (lc = 0; TEST_LOOPING(lc); lc++) { 110 111 /* Reset Tst_count in case we are looping. */ 112 Tst_count = 0; 113 114 /* 115 * Call poll() with the TEST macro. 116 */ 117 TEST(poll(fds, 1, -1)); 118 119 /* check return code of poll() */ 120 if (TEST_RETURN == -1) { 121 tst_resm(TFAIL, "poll() failed on write, errno=%d" 122 " : %s", TEST_ERRNO, strerror(TEST_ERRNO)); 123 continue; 124 } 125 126 /* write the message to the pipe */ 127 if (write(fildes[1], write_buf, sizeof(write_buf)) 128 < sizeof(write_buf)) { 129 tst_brkm(TBROK, cleanup, "write() failed on write " 130 "to pipe, error:%d", errno); 131 } 132 133 length=sizeof(write_buf); 134 135 /* Fork child process */ 136 if ((cpid = FORK_OR_VFORK()) == -1) { 137 tst_brkm(TBROK, cleanup, "fork() failed"); 138 } 139 140 if (cpid == 0) { /* Child process */ 141 /* 142 * close writing end of pipe and read from 143 * the pipe 144 */ 145 if (close(fildes[1]) == -1) { 146 tst_brkm(TFAIL, NULL, "close() failed on write " 147 "endof pipe, errno:%d", errno); 148 exit(1); 149 } 150 151 /* 152 * Set poll() data structures to check 153 * if data is present on read 154 */ 155 fds[0].fd = fildes[0]; 156 fds[0].events = POLLIN; 157 158 /* 159 * If data are present, then read the data. If poll() 160 * and read() return expected values, then the 161 * functionality of poll() is correct. 162 */ 163 rval = (poll(fds, 1, -1)); 164 165 if (rval == -1) { 166 tst_resm(TFAIL, "poll() failed on read - " 167 "errno=%d : %s", 168 TEST_ERRNO, strerror(errno)); 169 exit(1); 170 } 171 172 /* Read data from read end of pipe */ 173 if (read(fildes[0], read_buf, sizeof(read_buf)) != 174 sizeof(write_buf)) { 175 tst_brkm(TFAIL, NULL, "read() failed - " 176 "error:%d", errno); 177 exit(1); 178 } 179 180 /* Now, do the actual comparision */ 181 if (strcmp(read_buf, write_buf)) { 182 tst_resm(TFAIL, "Data from reading pipe " 183 "are different"); 184 printf(" read_buf is %s\n write_buf is %s\n length is %d\n",read_buf,write_buf,length); 185 exit(1); 186 } 187 188 /* Everything is fine, exit normally */ 189 exit(0); 190 } else { /* Parent process */ 191 /* Wait for child to complete execution */ 192 wait(&status); 193 194 if (WEXITSTATUS(status) == 1) { 195 tst_resm(TFAIL, "child exited abnormally"); 196 } else { 197 tst_resm(TPASS, 198 "Functionality of poll() successful"); 199 } 200 } 201 } /* End for TEST_LOOPING */ 202 203 /* Call cleanup() to undo setup done for the test. */ 204 cleanup(); 205 206 /*NOTREACHED*/ 207 return 0; 208} /* End main */ 209 210/* 211 * setup() - performs all ONE TIME setup for this test. 212 * Creat read/write pipe using pipe(). 213 * Set poll data structures to check writing to the pipe. 214 */ 215void 216setup() 217{ 218 /* capture signals */ 219 tst_sig(FORK, DEF_HANDLER, cleanup); 220 221 /* Pause if that option was specified */ 222 TEST_PAUSE; 223 224 /* Creat read/write pipe */ 225 if (pipe(fildes) < 0) { 226 tst_brkm(TBROK, tst_exit, 227 "pipe() failed to create interprocess channel"); 228 } 229 230 /* Set poll data structures */ 231 fds[0].fd = fildes[1]; 232 fds[0].events = POLLOUT; 233} 234 235/* 236 * cleanup() - performs all ONE TIME cleanup for this test at 237 * completion or premature exit. 238 * close read end of pipe if still open. 239 */ 240void 241cleanup() 242{ 243 /* 244 * print timing stats if that option was specified. 245 * print errno log if that option was specified. 246 */ 247 TEST_CLEANUP; 248 249 /* close read end of pipe if still open */ 250 if (close(fildes[0]) < 0) { 251 tst_brkm(TFAIL, NULL, "close() failed on read-end of pipe, " 252 "errno:%d", errno); 253 } 254 255 /* exit with return code appropriate for results */ 256 tst_exit(); 257} 258