source: trunk/minix/test/select/test11.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 4.0 KB
Line 
1/*
2 * Test name: test11.c
3 *
4 * Objetive: The purpose of this test is to make sure that select works
5 * with pipes.
6 *
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.
16 *
17 * Jose M. Gomez
18 */
19
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>
32
33void pipehandler(int sig)
34{
35
36}
37
38void do_child(int data_pipe[])
39{
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;
46
47 signal(SIGPIPE, pipehandler);
48 signal(SIGUSR1, pipehandler);
49
50 /* first, close the write part of the pipe, since it is not needed */
51 close(data_pipe[1]);
52
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;
69 }
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);
76 }
77 if(retval == 0) {
78 fprintf(stderr, "child: eof on pipe\n");
79 break;
80 }
81 data[retval] = '\0';
82 printf("pid %d Pipe reads (%d): %s\n", getpid(), retval, data);
83 } else printf("child: no fd set\n");
84 }
85
86 /* probably pipe was broken, or got EOF via the pipe. */
87 exit(0);
88}
89
90void do_parent(int data_pipe[])
91{
92 char data[1024];
93 int retval;
94 fd_set fds_write;
95
96 signal(SIGPIPE, pipehandler);
97 signal(SIGUSR1, pipehandler);
98
99 /* first, close the read part of pipe, since it is not needed */
100 close(data_pipe[0]);
101
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);
112 }
113
114 printf("Input data: ");
115 if(!gets(data)) {
116 printf("parent: eof; exiting\n");
117 break;
118 }
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;
124 }
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);
130 }
131 }
132
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);
138}
139
140void main(void) {
141 int pipes[2];
142 int retval;
143 int pid;
144
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);
151 }
152 pid = fork();
153 if (pid == -1) {
154 fprintf(stderr, "Error forking\n");
155 exit(-1);
156 }
157
158 if (pid == 0) /* child proc */
159 do_child(pipes);
160 else
161 do_parent(pipes);
162}
Note: See TracBrowser for help on using the repository browser.