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