kernel: print spurious interrupt message with increasing interval.
[minix.git] / test / select / test11.c
blob5126f60cd5128ce758527dfd49598df76873c5b7
1 /*
2 * Test name: test11.c
4 * Objetive: The purpose of this test is to make sure that select works
5 * with pipes.
7 * Description: The select checks are divided in checks on writing for the
8 * parent process, which has the writing end of the pipe, and checks on reading
9 * and exception on the child process, which has the reading end of pipe. So
10 * when the first process is ready to write to the pipe it will request a string
11 * from the terminal and send it through the pipe. If the string is 'exit' then
12 * the pipe is closed. The child process is blocked in a select checking for read
13 * and exception. If there is data to be read then it will perform the read and
14 * prints the read data. If the pipe is closed (user typed 'exit'), the child
15 * process finishes.
17 * Jose M. Gomez
20 #include <time.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include <sys/asynchio.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <sys/select.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include <string.h>
31 #include <signal.h>
33 void pipehandler(int sig)
38 void do_child(int data_pipe[])
40 /* reads from pipe and prints out the data */
41 char data[2048];
42 int retval;
43 fd_set fds_read;
44 fd_set fds_exception;
45 struct timeval timeout;
47 signal(SIGPIPE, pipehandler);
48 signal(SIGUSR1, pipehandler);
50 /* first, close the write part of the pipe, since it is not needed */
51 close(data_pipe[1]);
53 while(1) {
54 FD_ZERO(&fds_read);
55 FD_ZERO(&fds_exception);
56 FD_SET(data_pipe[0], &fds_read);
57 FD_SET(data_pipe[0], &fds_exception);
58 timeout.tv_sec = 5;
59 timeout.tv_usec = 0;
60 retval = select(data_pipe[0]+1, &fds_read, NULL, &fds_exception, &timeout);
61 if (retval == -1) {
62 perror("select");
63 fprintf(stderr, "child: Error in select\n");
64 continue;
65 } else printf("child select: %d\n", retval);
66 if (FD_ISSET(data_pipe[0], &fds_exception)) {
67 printf("child: exception fd set. quitting.\n");
68 break;
70 if (FD_ISSET(data_pipe[0], &fds_read)) {
71 printf("child: read fd set. reading.\n");
72 if ((retval = read(data_pipe[0], data, sizeof(data))) < 0) {
73 perror("read");
74 fprintf(stderr, "child: couldn't read from pipe\n");
75 exit(-1);
77 if(retval == 0) {
78 fprintf(stderr, "child: eof on pipe\n");
79 break;
81 data[retval] = '\0';
82 printf("pid %d Pipe reads (%d): %s\n", getpid(), retval, data);
83 } else printf("child: no fd set\n");
86 /* probably pipe was broken, or got EOF via the pipe. */
87 exit(0);
90 void do_parent(int data_pipe[])
92 char data[1024];
93 int retval;
94 fd_set fds_write;
96 signal(SIGPIPE, pipehandler);
97 signal(SIGUSR1, pipehandler);
99 /* first, close the read part of pipe, since it is not needed */
100 close(data_pipe[0]);
102 /* now enter a loop of read user input, and writing it to the pipe */
103 while (1) {
104 FD_ZERO(&fds_write);
105 FD_SET(data_pipe[1], &fds_write);
106 printf("pid %d Waiting for pipe ready to write...\n", getpid());
107 retval = select(data_pipe[1]+1, NULL, &fds_write, NULL, NULL);
108 if (retval == -1) {
109 perror("select");
110 fprintf(stderr, "Parent: Error in select\n");
111 exit(-1);
114 printf("Input data: ");
115 if(!gets(data)) {
116 printf("parent: eof; exiting\n");
117 break;
119 if (!strcmp(data, "exit"))
120 break;
121 if (!FD_ISSET(data_pipe[1], &fds_write)) {
122 fprintf(stderr, "parent: write fd not set?! retrying\n");
123 continue;
125 retval = write(data_pipe[1], &data, 1024);
126 if (retval == -1) {
127 perror("write");
128 fprintf(stderr, "Error writing on pipe\n");
129 exit(-1);
133 /* got exit from user */
134 close(data_pipe[1]); /* close pipe, let child know we're done */
135 wait(&retval);
136 printf("Child exited with status: %d\n", retval);
137 exit(0);
140 void main(void) {
141 int pipes[2];
142 int retval;
143 int pid;
145 /* create the pipe */
146 retval = pipe(pipes);
147 if (retval == -1) {
148 perror("pipe");
149 fprintf(stderr, "Error creating the pipe\n");
150 exit(-1);
152 pid = fork();
153 if (pid == -1) {
154 fprintf(stderr, "Error forking\n");
155 exit(-1);
158 if (pid == 0) /* child proc */
159 do_child(pipes);
160 else
161 do_parent(pipes);