xref: /original-bsd/usr.bin/talk/io.c (revision fa921481)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)io.c	5.5 (Berkeley) 06/01/90";
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 <sys/time.h>
19 #include "talk.h"
20 #include <stdio.h>
21 #include <errno.h>
22 #include <string.h>
23 
24 #define A_LONG_TIME 10000000
25 #define STDIN_MASK (1<<fileno(stdin))	/* the bit mask for standard
26 					   input */
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 
87 /*
88  * p_error prints the system error message on the standard location
89  * on the screen and then exits. (i.e. a curses version of perror)
90  */
91 p_error(string)
92 	char *string;
93 {
94 	wmove(my_win.x_win, current_line%my_win.x_nlines, 0);
95 	wprintw(my_win.x_win, "[%s : %s (%d)]\n",
96 	    string, strerror(errno), errno);
97 	wrefresh(my_win.x_win);
98 	move(LINES-1, 0);
99 	refresh();
100 	quit();
101 }
102 
103 /*
104  * Display string in the standard location
105  */
106 message(string)
107 	char *string;
108 {
109 
110 	wmove(my_win.x_win, current_line%my_win.x_nlines, 0);
111 	wprintw(my_win.x_win, "[%s]\n", string);
112 	wrefresh(my_win.x_win);
113 }
114