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