1*16364Skarels #ifndef lint 2*16364Skarels static char sccsid[] = "@(#)io.c 1.2 (Berkeley) 04/11/84"; 3*16364Skarels #endif 416351Skarels 5*16364Skarels /* 6*16364Skarels * This file contains the I/O handling and the exchange of 7*16364Skarels * edit characters. This connection itself is established in 8*16364Skarels * ctl.c 916351Skarels */ 1016351Skarels 1116351Skarels #include "talk.h" 1216351Skarels #include <stdio.h> 1316351Skarels #include <errno.h> 1416351Skarels #include <sys/time.h> 1516351Skarels 1616351Skarels #define A_LONG_TIME 10000000 1716351Skarels #define STDIN_MASK (1<<fileno(stdin)) /* the bit mask for standard 1816351Skarels input */ 1916351Skarels extern int errno; 2016351Skarels 2116351Skarels /* 2216351Skarels * The routine to do the actual talking 2316351Skarels */ 2416351Skarels talk() 2516351Skarels { 26*16364Skarels register int read_template, sockt_mask; 27*16364Skarels int read_set, nb; 28*16364Skarels char buf[BUFSIZ]; 29*16364Skarels struct timeval wait; 3016351Skarels 31*16364Skarels message("Connection established\007\007\007"); 32*16364Skarels current_line = 0; 33*16364Skarels sockt_mask = (1<<sockt); 3416351Skarels 3516351Skarels /* 36*16364Skarels * Wait on both the other process (sockt_mask) and 3716351Skarels * standard input ( STDIN_MASK ) 3816351Skarels */ 39*16364Skarels read_template = sockt_mask | STDIN_MASK; 40*16364Skarels forever { 4116351Skarels read_set = read_template; 42*16364Skarels wait.tv_sec = A_LONG_TIME; 43*16364Skarels wait.tv_usec = 0; 44*16364Skarels nb = select(32, &read_set, 0, 0, &wait); 45*16364Skarels if (nb <= 0) { 46*16364Skarels if (errno == EINTR) { 47*16364Skarels read_set = read_template; 48*16364Skarels continue; 49*16364Skarels } 50*16364Skarels /* panic, we don't know what happened */ 51*16364Skarels p_error("Unexpected error from select"); 52*16364Skarels quit(); 53*16364Skarels } 54*16364Skarels if (read_set & sockt_mask) { 55*16364Skarels /* There is data on sockt */ 56*16364Skarels nb = read(sockt, buf, sizeof buf); 57*16364Skarels if (nb <= 0) { 58*16364Skarels message("Connection closed. Exiting"); 59*16364Skarels quit(); 60*16364Skarels } 61*16364Skarels display(&his_win, buf, nb); 62*16364Skarels } 63*16364Skarels if (read_set & STDIN_MASK) { 64*16364Skarels /* 65*16364Skarels * We can't make the tty non_blocking, because 66*16364Skarels * curses's output routines would screw up 67*16364Skarels */ 68*16364Skarels ioctl(0, FIONREAD, (struct sgttyb *) &nb); 69*16364Skarels nb = read(0, buf, nb); 70*16364Skarels display(&my_win, buf, nb); 71*16364Skarels /* might lose data here because sockt is non-blocking */ 72*16364Skarels write(sockt, buf, nb); 73*16364Skarels } 7416351Skarels } 7516351Skarels } 7616351Skarels 77*16364Skarels extern int errno; 78*16364Skarels extern int sys_nerr; 79*16364Skarels extern char *sys_errlist[]; 8016351Skarels 81*16364Skarels /* 82*16364Skarels * p_error prints the system error message on the standard location 83*16364Skarels * on the screen and then exits. (i.e. a curses version of perror) 84*16364Skarels */ 8516351Skarels p_error(string) 86*16364Skarels char *string; 8716351Skarels { 88*16364Skarels char *sys; 8916351Skarels 90*16364Skarels sys = "Unknown error"; 91*16364Skarels if (errno < sys_nerr) 92*16364Skarels sys = sys_errlist[errno]; 93*16364Skarels wmove(my_win.x_win, current_line%my_win.x_nlines, 0); 94*16364Skarels wprintw(my_win.x_win, "[%s : %s (%d)]\n", string, sys, errno); 95*16364Skarels wrefresh(my_win.x_win); 96*16364Skarels move(LINES-1, 0); 97*16364Skarels refresh(); 98*16364Skarels quit(); 9916351Skarels } 10016351Skarels 101*16364Skarels /* 102*16364Skarels * Display string in the standard location 103*16364Skarels */ 10416351Skarels message(string) 105*16364Skarels char *string; 10616351Skarels { 107*16364Skarels 108*16364Skarels wmove(my_win.x_win, current_line%my_win.x_nlines, 0); 109*16364Skarels wprintw(my_win.x_win, "[%s]\n", string); 110*16364Skarels wrefresh(my_win.x_win); 11116351Skarels } 112