Commit | Line | Data |
---|---|---|
963ce42e MK |
1 | #ifndef lint |
2 | static char sccsid[] = "@(#)io.c 1.2 (Berkeley) %G%"; | |
3 | #endif | |
e851d673 | 4 | |
963ce42e MK |
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 | |
e851d673 MK |
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 | */ | |
e851d673 MK |
24 | talk() |
25 | { | |
963ce42e MK |
26 | register int read_template, sockt_mask; |
27 | int read_set, nb; | |
28 | char buf[BUFSIZ]; | |
29 | struct timeval wait; | |
e851d673 | 30 | |
963ce42e MK |
31 | message("Connection established\007\007\007"); |
32 | current_line = 0; | |
33 | sockt_mask = (1<<sockt); | |
e851d673 MK |
34 | |
35 | /* | |
963ce42e | 36 | * Wait on both the other process (sockt_mask) and |
e851d673 MK |
37 | * standard input ( STDIN_MASK ) |
38 | */ | |
963ce42e MK |
39 | read_template = sockt_mask | STDIN_MASK; |
40 | forever { | |
e851d673 | 41 | read_set = read_template; |
963ce42e MK |
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 | } | |
e851d673 | 74 | } |
e851d673 MK |
75 | } |
76 | ||
963ce42e MK |
77 | extern int errno; |
78 | extern int sys_nerr; | |
79 | extern char *sys_errlist[]; | |
e851d673 | 80 | |
963ce42e MK |
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 | */ | |
e851d673 | 85 | p_error(string) |
963ce42e | 86 | char *string; |
e851d673 | 87 | { |
963ce42e MK |
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(); | |
e851d673 MK |
99 | } |
100 | ||
963ce42e MK |
101 | /* |
102 | * Display string in the standard location | |
103 | */ | |
e851d673 | 104 | message(string) |
963ce42e | 105 | char *string; |
e851d673 | 106 | { |
963ce42e MK |
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); | |
e851d673 | 111 | } |