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