// File: termdemo.c // Demo of select, with terminal functions, too. #include #include #include #include #include #include #include #define READ_END 0 #define WRITE_END 1 void main(argc, argv) int argc ; char *argv[] ; { int PipeDes[2] ; // pipe int Child ; // there's going to be a fork int i; int OwnPid = getpid() ; // hold own pid fd_set fdvar ; // The file descriptor set int ReadEnd, UserRead ; // Pipe ends FILE *fp ; // Open a file int done = 0, RetVal ; char buf[20],command ; struct termios term, termsave ; /*** attach fp to stdin ***/ fp = fopen(ctermid(NULL), "r+") ; setbuf(fp, NULL) ; // No buffering of input UserRead = fileno(fp) ; // UserRead will be the terminal's fd if(pipe(PipeDes)<0) { perror("Pipe error ") ; exit(1) ; } if((Child=fork())==0) /*** if child process ***/ { close(PipeDes[READ_END]) ; for(i=65; i<74; i++) // 'A' through 'J' { write(PipeDes[WRITE_END], &i, sizeof(i)) ; sleep(1) ; } i = -1 ; write(PipeDes[WRITE_END], &i, sizeof(int)) ; } // child else if(Child>0) /*** if parent process ***/ { close(PipeDes[WRITE_END]) ; ReadEnd = PipeDes[READ_END] ; while(!done) { FD_ZERO(&fdvar) ; FD_SET(ReadEnd, &fdvar) ; FD_SET(UserRead, &fdvar) ; // Get parameters of terminal; place into itermios struct termsave tcgetattr(UserRead, &termsave) ; // want to save initial condition, so will manipulate term term = termsave ; // echo characters. Allow any size input. See termios man page // term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON) ; term.c_lflag &= (ECHO) ; // Record changes to UserRead made by changing the c_lflag tcsetattr(UserRead, TCSANOW, &term) ; // Set up the select to listen; only using read fds (others are null) select(32, &fdvar, (fd_set *)0, (fd_set *)0, NULL ) ; // Restore UserRead to default after output tcsetattr(UserRead, /* TCSAFLUSH */ TCSADRAIN, &termsave); if(FD_ISSET(ReadEnd, &fdvar)) { read(ReadEnd, &i, sizeof(int)) ; if(i==-1) done++ ; else write(1, &i,sizeof(i)); } if(FD_ISSET(UserRead, &fdvar)) { if((RetVal=read(UserRead, buf, sizeof(buf)))>1) { fprintf(stderr,"Stdin: %d chars -- %s\n",RetVal,buf); write(1, buf, RetVal) ; sleep(1); } } printf("\n") ; } } // Parent else { perror("Fork error ") ; exit(1) ; } }