xref: /minix/minix/tests/t40b.c (revision 7f5f010b)
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