summaryrefslogtreecommitdiff
path: root/minix/tests/t40b.c
blob: 5339549773f1d46045068b2706483f38d0ef06a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* t40b.c
 *
 * Test regular files
 *
 * Select works on regular files, (pseudo) terminal devices, streams-based
 * files, FIFOs, pipes, and sockets. This test verifies selecting for regular
 * file descriptors. "File descriptors associated with regular files shall
 * always select true for ready to read, ready to write, and error conditions"
 * - Open Group. Although we set a timeout, the select should return
 * immediately.
 *
 * This test is part of a bigger select test. It expects as argument which sub-
 * test it is.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <errno.h>
#include <time.h>

#include "common.h"

#define FILE1 "selecttestb-1"
#define FILES 2
#define TIME 3

#define MAX_ERROR 10

char errorbuf[1000];

int main(int argc, char **argv) {
  int fd1, fd2, retval;
  fd_set fds_read, fds_write, fds_error;
  struct timeval tv;
  time_t start, end;

  /* Get subtest number */
  if(argc != 2) {
    printf("Usage: %s subtest_no\n", argv[0]);
    exit(-1);
  } else if(sscanf(argv[1], "%d", &subtest) != 1) {
    printf("Usage: %s subtest_no\n", argv[0]);
    exit(-1);
  }

  /* Set timeout */
  tv.tv_sec = TIME;
  tv.tv_usec = 0;
  
  /* Open a file for writing */
  if((fd1 = open(FILE1, O_WRONLY|O_CREAT, 0644)) == -1) {
    snprintf(errorbuf, sizeof(errorbuf), "failed to open file %s for writing",
	     FILE1);
    em(1, errorbuf);
    perror(NULL);
    exit(1);
  }
  
  /* Open the same file for reading */ 
  if((fd2 = open(FILE1, O_RDONLY)) == -1) {
    snprintf(errorbuf, sizeof(errorbuf), "failed to open file %s for reading",
	     FILE1);
    em(2, errorbuf);
    perror(NULL);
    exit(1);
  }
  
  /* Clear file descriptor bit masks */
  FD_ZERO(&fds_read); FD_ZERO(&fds_write); FD_ZERO(&fds_error);
  
  /* Fill bit mask */
  FD_SET(fd1, &fds_write);
  FD_SET(fd2, &fds_read);
  FD_SET(fd1, &fds_error);
  FD_SET(fd2, &fds_error);

  /* Do the select and time how long it takes */
  start = time(NULL);
  retval =  select(fd2+1, &fds_read, &fds_write, &fds_error, &tv);
  end = time(NULL);

  /* Correct amount of ready file descriptors? 1 read + 1 write + 2 errors */
  if(retval != 4) {
    em(3, "four fds should be set");
  }

  /* Test resulting bit masks */
  if(!FD_ISSET(fd1, &fds_write)) em(4, "write should be set");
  if(!FD_ISSET(fd2, &fds_read)) em(5, "read should be set");
  if(!FD_ISSET(fd1, &fds_error)) em(6, "error should be set");
  if(!FD_ISSET(fd2, &fds_error)) em(7, "error should be set");

  /* Was it instantaneous? */
  if(end-start != TIME - TIME) {
    snprintf(errorbuf,sizeof(errorbuf),"time spent blocking is not %d, but %ld",
	     TIME - TIME, (long int) (end-start));
    em(8, errorbuf);
  }

  /* Wait for read to become ready on O_WRONLY. This should fail immediately. */
  FD_ZERO(&fds_read); FD_ZERO(&fds_write); FD_ZERO(&fds_error);
  FD_SET(fd1, &fds_read);
  FD_SET(fd1, &fds_error);
  FD_SET(fd2, &fds_error);
  tv.tv_sec = TIME;
  tv.tv_usec = 0;
  retval = select(fd2+1, &fds_read, NULL, &fds_error, &tv);

  /* Correct amount of ready file descriptors? 1 read + 2 error */
  if(retval != 3) em(9, "incorrect amount of ready file descriptors");
  if(!FD_ISSET(fd1, &fds_read)) em(10, "read should be set");
  if(!FD_ISSET(fd1, &fds_error)) em(11, "error should be set");
  if(!FD_ISSET(fd2, &fds_error)) em(12, "error should be set");

  /* Try again as above, bit this time with O_RDONLY in the write set */
  FD_ZERO(&fds_error);
  FD_SET(fd2, &fds_write);
  FD_SET(fd1, &fds_error);
  FD_SET(fd2, &fds_error);
  tv.tv_sec = TIME;
  tv.tv_usec = 0;
  retval = select(fd2+1, NULL, &fds_write, &fds_error, &tv);
  
  /* Correct amount of ready file descriptors? 1 write + 2 errors */
  if(retval != 3) em(13, "incorrect amount of ready file descriptors");
  if(!FD_ISSET(fd2, &fds_write)) em(14, "write should be set");
  if(!FD_ISSET(fd1, &fds_error)) em(15, "error should be set");
  if(!FD_ISSET(fd2, &fds_error)) em(16, "error should be set");
  
  close(fd1);
  close(fd2);
  unlink(FILE1);
  
  exit(errct);
}