1 /* t40b.c 2 * 3 * Test regular files 4 * 5 * Select works on regular files, (pseudo) terminal devices, streams-based 6 * files, FIFOs, pipes, and sockets. This test verifies selecting for regular 7 * file descriptors. "File descriptors associated with regular files shall 8 * always select true for ready to read, ready to write, and error conditions" 9 * - Open Group. Although we set a timeout, the select should return 10 * immediately. 11 * 12 * This test is part of a bigger select test. It expects as argument which sub- 13 * test it is. 14 */ 15 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <unistd.h> 19 #include <sys/types.h> 20 #include <sys/stat.h> 21 #include <fcntl.h> 22 #include <sys/select.h> 23 #include <errno.h> 24 #include <time.h> 25 26 #include "common.h" 27 28 #define FILE1 "selecttestb-1" 29 #define FILES 2 30 #define TIME 3 31 32 #define MAX_ERROR 10 33 34 char errorbuf[1000]; 35 36 int main(int argc, char **argv) { 37 int fd1, fd2, retval; 38 fd_set fds_read, fds_write, fds_error; 39 struct timeval tv; 40 time_t start, end; 41 42 /* Get subtest number */ 43 if(argc != 2) { 44 printf("Usage: %s subtest_no\n", argv[0]); 45 exit(-1); 46 } else if(sscanf(argv[1], "%d", &subtest) != 1) { 47 printf("Usage: %s subtest_no\n", argv[0]); 48 exit(-1); 49 } 50 51 /* Set timeout */ 52 tv.tv_sec = TIME; 53 tv.tv_usec = 0; 54 55 /* Open a file for writing */ 56 if((fd1 = open(FILE1, O_WRONLY|O_CREAT, 0644)) == -1) { 57 snprintf(errorbuf, sizeof(errorbuf), "failed to open file %s for writing", 58 FILE1); 59 em(1, errorbuf); 60 perror(NULL); 61 exit(1); 62 } 63 64 /* Open the same file for reading */ 65 if((fd2 = open(FILE1, O_RDONLY)) == -1) { 66 snprintf(errorbuf, sizeof(errorbuf), "failed to open file %s for reading", 67 FILE1); 68 em(2, errorbuf); 69 perror(NULL); 70 exit(1); 71 } 72 73 /* Clear file descriptor bit masks */ 74 FD_ZERO(&fds_read); FD_ZERO(&fds_write); FD_ZERO(&fds_error); 75 76 /* Fill bit mask */ 77 FD_SET(fd1, &fds_write); 78 FD_SET(fd2, &fds_read); 79 FD_SET(fd1, &fds_error); 80 FD_SET(fd2, &fds_error); 81 82 /* Do the select and time how long it takes */ 83 start = time(NULL); 84 retval = select(fd2+1, &fds_read, &fds_write, &fds_error, &tv); 85 end = time(NULL); 86 87 /* Correct amount of ready file descriptors? 1 read + 1 write + 2 errors */ 88 if(retval != 4) { 89 em(3, "four fds should be set"); 90 } 91 92 /* Test resulting bit masks */ 93 if(!FD_ISSET(fd1, &fds_write)) em(4, "write should be set"); 94 if(!FD_ISSET(fd2, &fds_read)) em(5, "read should be set"); 95 if(!FD_ISSET(fd1, &fds_error)) em(6, "error should be set"); 96 if(!FD_ISSET(fd2, &fds_error)) em(7, "error should be set"); 97 98 /* Was it instantaneous? */ 99 if(end-start != TIME - TIME) { 100 snprintf(errorbuf,sizeof(errorbuf),"time spent blocking is not %d, but %ld", 101 TIME - TIME, (long int) (end-start)); 102 em(8, errorbuf); 103 } 104 105 /* Wait for read to become ready on O_WRONLY. This should fail immediately. */ 106 FD_ZERO(&fds_read); FD_ZERO(&fds_write); FD_ZERO(&fds_error); 107 FD_SET(fd1, &fds_read); 108 FD_SET(fd1, &fds_error); 109 FD_SET(fd2, &fds_error); 110 tv.tv_sec = TIME; 111 tv.tv_usec = 0; 112 retval = select(fd2+1, &fds_read, NULL, &fds_error, &tv); 113 114 /* Correct amount of ready file descriptors? 1 read + 2 error */ 115 if(retval != 3) em(9, "incorrect amount of ready file descriptors"); 116 if(!FD_ISSET(fd1, &fds_read)) em(10, "read should be set"); 117 if(!FD_ISSET(fd1, &fds_error)) em(11, "error should be set"); 118 if(!FD_ISSET(fd2, &fds_error)) em(12, "error should be set"); 119 120 /* Try again as above, bit this time with O_RDONLY in the write set */ 121 FD_ZERO(&fds_error); 122 FD_SET(fd2, &fds_write); 123 FD_SET(fd1, &fds_error); 124 FD_SET(fd2, &fds_error); 125 tv.tv_sec = TIME; 126 tv.tv_usec = 0; 127 retval = select(fd2+1, NULL, &fds_write, &fds_error, &tv); 128 129 /* Correct amount of ready file descriptors? 1 write + 2 errors */ 130 if(retval != 3) em(13, "incorrect amount of ready file descriptors"); 131 if(!FD_ISSET(fd2, &fds_write)) em(14, "write should be set"); 132 if(!FD_ISSET(fd1, &fds_error)) em(15, "error should be set"); 133 if(!FD_ISSET(fd2, &fds_error)) em(16, "error should be set"); 134 135 close(fd1); 136 close(fd2); 137 unlink(FILE1); 138 139 exit(errct); 140 } 141