1 /*
2 * Copyright (c) 1983, 1993
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 8.1 (Berkeley) 06/06/93";
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/ioctl.h>
19 #include <sys/time.h>
20 #include <stdio.h>
21 #include <errno.h>
22 #include <string.h>
23 #include "talk.h"
24
25 #define A_LONG_TIME 10000000
26 #define STDIN_MASK (1<<fileno(stdin)) /* the bit mask for standard
27 input */
28
29 /*
30 * The routine to do the actual talking
31 */
talk()32 talk()
33 {
34 register int read_template, sockt_mask;
35 int read_set, nb;
36 char buf[BUFSIZ];
37 struct timeval wait;
38
39 message("Connection established\007\007\007");
40 current_line = 0;
41 sockt_mask = (1<<sockt);
42
43 /*
44 * Wait on both the other process (sockt_mask) and
45 * standard input ( STDIN_MASK )
46 */
47 read_template = sockt_mask | STDIN_MASK;
48 for (;;) {
49 read_set = read_template;
50 wait.tv_sec = A_LONG_TIME;
51 wait.tv_usec = 0;
52 nb = select(32, &read_set, 0, 0, &wait);
53 if (nb <= 0) {
54 if (errno == EINTR) {
55 read_set = read_template;
56 continue;
57 }
58 /* panic, we don't know what happened */
59 p_error("Unexpected error from select");
60 quit();
61 }
62 if (read_set & sockt_mask) {
63 /* There is data on sockt */
64 nb = read(sockt, buf, sizeof buf);
65 if (nb <= 0) {
66 message("Connection closed. Exiting");
67 quit();
68 }
69 display(&his_win, buf, nb);
70 }
71 if (read_set & STDIN_MASK) {
72 /*
73 * We can't make the tty non_blocking, because
74 * curses's output routines would screw up
75 */
76 ioctl(0, FIONREAD, (struct sgttyb *) &nb);
77 nb = read(0, buf, nb);
78 display(&my_win, buf, nb);
79 /* might lose data here because sockt is non-blocking */
80 write(sockt, buf, nb);
81 }
82 }
83 }
84
85 extern int errno;
86 extern int sys_nerr;
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 */
p_error(string)92 p_error(string)
93 char *string;
94 {
95 wmove(my_win.x_win, current_line%my_win.x_nlines, 0);
96 wprintw(my_win.x_win, "[%s : %s (%d)]\n",
97 string, strerror(errno), errno);
98 wrefresh(my_win.x_win);
99 move(LINES-1, 0);
100 refresh();
101 quit();
102 }
103
104 /*
105 * Display string in the standard location
106 */
message(string)107 message(string)
108 char *string;
109 {
110 wmove(my_win.x_win, current_line % my_win.x_nlines, 0);
111 wprintw(my_win.x_win, "[%s]", string);
112 wclrtoeol(my_win.x_win);
113 current_line++;
114 wmove(my_win.x_win, current_line % my_win.x_nlines, 0);
115 wrefresh(my_win.x_win);
116 }
117