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