xref: /original-bsd/usr.bin/talk/io.c (revision e74403ba)
1 #ifndef lint
2 static char sccsid[] = "@(#)io.c	1.2 (Berkeley) 04/11/84";
3 #endif
4 
5 /*
6  * This file contains the I/O handling and the exchange of
7  * edit characters. This connection itself is established in
8  * ctl.c
9  */
10 
11 #include "talk.h"
12 #include <stdio.h>
13 #include <errno.h>
14 #include <sys/time.h>
15 
16 #define A_LONG_TIME 10000000
17 #define STDIN_MASK (1<<fileno(stdin))	/* the bit mask for standard
18 					   input */
19 extern int errno;
20 
21 /*
22  * The routine to do the actual talking
23  */
24 talk()
25 {
26 	register int read_template, sockt_mask;
27 	int read_set, nb;
28 	char buf[BUFSIZ];
29 	struct timeval wait;
30 
31 	message("Connection established\007\007\007");
32 	current_line = 0;
33 	sockt_mask = (1<<sockt);
34 
35 	/*
36 	 * Wait on both the other process (sockt_mask) and
37 	 * standard input ( STDIN_MASK )
38 	 */
39 	read_template = sockt_mask | STDIN_MASK;
40 	forever {
41 		read_set = read_template;
42 		wait.tv_sec = A_LONG_TIME;
43 		wait.tv_usec = 0;
44 		nb = select(32, &read_set, 0, 0, &wait);
45 		if (nb <= 0) {
46 			if (errno == EINTR) {
47 				read_set = read_template;
48 				continue;
49 			}
50 			/* panic, we don't know what happened */
51 			p_error("Unexpected error from select");
52 			quit();
53 		}
54 		if (read_set & sockt_mask) {
55 			/* There is data on sockt */
56 			nb = read(sockt, buf, sizeof buf);
57 			if (nb <= 0) {
58 				message("Connection closed. Exiting");
59 				quit();
60 			}
61 			display(&his_win, buf, nb);
62 		}
63 		if (read_set & STDIN_MASK) {
64 			/*
65 			 * We can't make the tty non_blocking, because
66 			 * curses's output routines would screw up
67 			 */
68 			ioctl(0, FIONREAD, (struct sgttyb *) &nb);
69 			nb = read(0, buf, nb);
70 			display(&my_win, buf, nb);
71 			/* might lose data here because sockt is non-blocking */
72 			write(sockt, buf, nb);
73 		}
74 	}
75 }
76 
77 extern	int errno;
78 extern	int sys_nerr;
79 extern	char *sys_errlist[];
80 
81 /*
82  * p_error prints the system error message on the standard location
83  * on the screen and then exits. (i.e. a curses version of perror)
84  */
85 p_error(string)
86 	char *string;
87 {
88 	char *sys;
89 
90 	sys = "Unknown error";
91 	if (errno < sys_nerr)
92 		sys = sys_errlist[errno];
93 	wmove(my_win.x_win, current_line%my_win.x_nlines, 0);
94 	wprintw(my_win.x_win, "[%s : %s (%d)]\n", string, sys, errno);
95 	wrefresh(my_win.x_win);
96 	move(LINES-1, 0);
97 	refresh();
98 	quit();
99 }
100 
101 /*
102  * Display string in the standard location
103  */
104 message(string)
105 	char *string;
106 {
107 
108 	wmove(my_win.x_win, current_line%my_win.x_nlines, 0);
109 	wprintw(my_win.x_win, "[%s]\n", string);
110 	wrefresh(my_win.x_win);
111 }
112