xref: /csrg-svn/usr.bin/talk/io.c (revision 16364)
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