source: trunk/minix/test/select/test14.c@ 22

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

Minix 3.1.2a

File size: 3.5 KB
Line 
1/*
2 * Test name: test14.c
3 *
4 * Objetive: The purpose of this test is to make sure that select works
5 * with ptys.
6 *
7 * Adapted from test11.c (pipe test).
8 *
9 * Ben Gras
10 */
11#include <time.h>
12#include <sys/types.h>
13#include <sys/wait.h>
14#include <sys/asynchio.h>
15#include <fcntl.h>
16#include <unistd.h>
17#include <sys/select.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <limits.h>
21#include <string.h>
22#include <signal.h>
23#include <libutil.h>
24char name[100];
25void pipehandler(int sig)
26{
27}
28#define CHILDFD 1
29#define PARENTFD 0
30void do_child(int pty_fds[])
31{
32 /* reads from pipe and prints out the data */
33 char data[2048];
34 int retval;
35 fd_set fds_read;
36 fd_set fds_exception;
37 struct timeval timeout;
38 signal(SIGPIPE, pipehandler);
39 signal(SIGUSR1, pipehandler);
40 /* first, close the write part, since it is not needed */
41 close(pty_fds[PARENTFD]);
42
43 while(1) {
44 FD_ZERO(&fds_read);
45 FD_ZERO(&fds_exception);
46 FD_SET(pty_fds[CHILDFD], &fds_read);
47 FD_SET(pty_fds[CHILDFD], &fds_exception);
48 timeout.tv_sec = 5;
49 timeout.tv_usec = 0;
50 retval = select(pty_fds[CHILDFD]+2, &fds_read, NULL, &fds_exception, &timeout);
51 if (retval == -1) {
52 perror("select");
53 fprintf(stderr, "child: Error in select\n");
54 continue;
55 } else printf("child select: %d\n", retval);
56 if (FD_ISSET(pty_fds[CHILDFD], &fds_exception)) {
57 printf("child: exception fd set. quitting.\n");
58 break;
59 }
60 if (FD_ISSET(pty_fds[CHILDFD], &fds_read)) {
61 printf("child: read fd set. reading.\n");
62 if ((retval = read(pty_fds[CHILDFD], data, sizeof(data))) < 0) {
63 perror("read");
64 fprintf(stderr, "child: couldn't read from pty\n");
65 exit(-1);
66 }
67 if(retval == 0) {
68 fprintf(stderr, "child: eof on pty\n");
69 break;
70 }
71 data[retval] = '\0';
72 printf("pid %d pty reads (%d): %s\n", getpid(), retval, data);
73 } else printf("child: no fd set\n");
74 }
75
76 exit(0);
77}
78void do_parent(int pty_fds[])
79{
80 char data[1024];
81 int retval;
82 fd_set fds_write;
83 signal(SIGPIPE, pipehandler);
84 signal(SIGUSR1, pipehandler);
85 /* first, close the read part of pty, since it is not needed */
86 close(pty_fds[CHILDFD]);
87 /* now enter a loop of read user input, and writing it to the pty */
88 while (1) {
89 FD_ZERO(&fds_write);
90 FD_SET(pty_fds[PARENTFD], &fds_write);
91 printf("pid %d Waiting for pty ready to write on %s...\n",
92 getpid(), name);
93 retval = select(pty_fds[PARENTFD]+2, NULL, &fds_write, NULL, NULL);
94 if (retval == -1) {
95 perror("select");
96 fprintf(stderr, "Parent: Error in select\n");
97 exit(-1);
98 }
99 printf("Input data: ");
100 if(!gets(data)) {
101 printf("parent: eof; exiting\n");
102 break;
103 }
104 if (!strcmp(data, "exit"))
105 break;
106 if (!FD_ISSET(pty_fds[PARENTFD], &fds_write)) {
107 fprintf(stderr, "parent: write fd not set?! retrying\n");
108 continue;
109 }
110 retval = write(pty_fds[PARENTFD], data, 1024);
111 if (retval == -1) {
112 perror("write");
113 fprintf(stderr, "Error writing on pty\n");
114 exit(-1);
115 } else printf("wrote %d\n", retval);
116 }
117 /* got exit from user */
118 close(pty_fds[PARENTFD]); /* close pty, let child know we're done */
119 wait(&retval);
120 printf("Child exited with status: %d\n", retval);
121 exit(0);
122}
123int main(int argc, char *argv[])
124{
125 int ptys[2];
126 int retval;
127 int pid;
128 if(openpty(&ptys[0], &ptys[1], name, NULL, NULL) < 0) {
129 perror("openpty");
130 return 1;
131 }
132 printf("Using %s\n", name);
133 pid = fork();
134 if (pid == -1) {
135 fprintf(stderr, "Error forking\n");
136 exit(-1);
137 }
138 if (pid == 0) /* child proc */
139 do_child(ptys);
140 else
141 do_parent(ptys);
142 /* not reached */
143 return 0;
144}
Note: See TracBrowser for help on using the repository browser.