4 * Objetive: The purpose of this test is to make sure that select works
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
21 #include <sys/types.h>
23 #include <sys/asynchio.h>
26 #include <sys/select.h>
33 void pipehandler(int sig
)
38 void do_child(int data_pipe
[])
40 /* reads from pipe and prints out the data */
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 */
55 FD_ZERO(&fds_exception
);
56 FD_SET(data_pipe
[0], &fds_read
);
57 FD_SET(data_pipe
[0], &fds_exception
);
60 retval
= select(data_pipe
[0]+1, &fds_read
, NULL
, &fds_exception
, &timeout
);
63 fprintf(stderr
, "child: Error in select\n");
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");
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) {
74 fprintf(stderr
, "child: couldn't read from pipe\n");
78 fprintf(stderr
, "child: eof on pipe\n");
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. */
90 void do_parent(int data_pipe
[])
96 signal(SIGPIPE
, pipehandler
);
97 signal(SIGUSR1
, pipehandler
);
99 /* first, close the read part of pipe, since it is not needed */
102 /* now enter a loop of read user input, and writing it to the pipe */
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
);
110 fprintf(stderr
, "Parent: Error in select\n");
114 printf("Input data: ");
116 printf("parent: eof; exiting\n");
119 if (!strcmp(data
, "exit"))
121 if (!FD_ISSET(data_pipe
[1], &fds_write
)) {
122 fprintf(stderr
, "parent: write fd not set?! retrying\n");
125 retval
= write(data_pipe
[1], &data
, 1024);
128 fprintf(stderr
, "Error writing on pipe\n");
133 /* got exit from user */
134 close(data_pipe
[1]); /* close pipe, let child know we're done */
136 printf("Child exited with status: %d\n", retval
);
140 int main(int argc
, char *argv
[])
146 /* create the pipe */
147 retval
= pipe(pipes
);
150 fprintf(stderr
, "Error creating the pipe\n");
155 fprintf(stderr
, "Error forking\n");
159 if (pid
== 0) /* child proc */