/[LeafOK_CVS]/lbbs/src/io.c
ViewVC logotype

Annotation of /lbbs/src/io.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.27 - (hide annotations)
Sun May 11 11:33:44 2025 UTC (10 months ago) by sysadm
Branch: MAIN
Changes since 1.26: +8 -9 lines
Content type: text/x-csrc
Fix bug in handling broken pipe

1 sysadm 1.1 /***************************************************************************
2 sysadm 1.14 io.c - description
3     -------------------
4 sysadm 1.20 Copyright : (C) 2004-2025 by Leaflet
5     Email : leaflet@leafok.com
6 sysadm 1.1 ***************************************************************************/
7    
8     /***************************************************************************
9     * *
10     * This program is free software; you can redistribute it and/or modify *
11     * it under the terms of the GNU General Public License as published by *
12 sysadm 1.20 * the Free Software Foundation; either version 3 of the License, or *
13 sysadm 1.1 * (at your option) any later version. *
14     * *
15     ***************************************************************************/
16    
17     #include "io.h"
18 sysadm 1.16 #include "log.h"
19 sysadm 1.1 #include "common.h"
20 sysadm 1.22 #include <errno.h>
21 sysadm 1.1 #include <stdio.h>
22     #include <stdarg.h>
23 sysadm 1.9 #include <time.h>
24     #include <fcntl.h>
25     #include <unistd.h>
26 sysadm 1.22 #include <sys/select.h>
27 sysadm 1.5 #include <sys/ioctl.h>
28 sysadm 1.1
29 sysadm 1.14 int outc(char c)
30 sysadm 1.1 {
31 sysadm 1.14 int retval;
32 sysadm 1.1
33 sysadm 1.14 retval = fprintf(stdout, "%c", c);
34 sysadm 1.1
35 sysadm 1.14 return retval;
36 sysadm 1.1 }
37    
38 sysadm 1.14 int prints(const char *format, ...)
39 sysadm 1.1 {
40 sysadm 1.14 va_list args;
41     int retval;
42 sysadm 1.1
43 sysadm 1.14 va_start(args, format);
44     retval = vfprintf(stdout, format, args);
45     va_end(args);
46 sysadm 1.1
47 sysadm 1.14 return retval;
48 sysadm 1.1 }
49    
50 sysadm 1.14 int iflush()
51 sysadm 1.1 {
52 sysadm 1.14 int retval;
53 sysadm 1.6
54 sysadm 1.14 retval = fflush(stdout);
55 sysadm 1.6
56 sysadm 1.14 return retval;
57 sysadm 1.1 }
58    
59 sysadm 1.17 int igetch(int clear_buf)
60 sysadm 1.1 {
61 sysadm 1.18 // static input buffer
62 sysadm 1.22 static unsigned char buf[LINE_BUFFER_LEN];
63 sysadm 1.19 static ssize_t len = 0;
64 sysadm 1.18 static int pos = 0;
65    
66 sysadm 1.21 fd_set testfds;
67     struct timeval timeout;
68    
69 sysadm 1.22 unsigned char tmp[LINE_BUFFER_LEN];
70 sysadm 1.21 int ret;
71 sysadm 1.27 int out = '\0';
72 sysadm 1.18 int in_esc = 0;
73     int in_ascii = 0;
74     int in_control = 0;
75     int i = 0;
76 sysadm 1.26 int flags;
77 sysadm 1.1
78 sysadm 1.17 if (clear_buf)
79     {
80     pos = 0;
81     len = 0;
82    
83 sysadm 1.27 return '\0';
84 sysadm 1.17 }
85    
86 sysadm 1.21 while (!SYS_server_exit && pos >= len)
87 sysadm 1.14 {
88     FD_ZERO(&testfds);
89 sysadm 1.21 FD_SET(STDIN_FILENO, &testfds);
90 sysadm 1.9
91 sysadm 1.22 timeout.tv_sec = 0;
92     timeout.tv_usec = 100 * 1000; // 0.1 second
93 sysadm 1.9
94 sysadm 1.26 ret = select(STDIN_FILENO + 1, &testfds, NULL, NULL, &timeout);
95 sysadm 1.9
96 sysadm 1.21 if (ret < 0)
97 sysadm 1.14 {
98 sysadm 1.21 if (errno != EINTR)
99     {
100 sysadm 1.27 log_error("select() error (%d) !\n", errno);
101 sysadm 1.21 return KEY_NULL;
102     }
103     continue;
104 sysadm 1.14 }
105 sysadm 1.21 else if (ret == 0)
106 sysadm 1.14 {
107 sysadm 1.21 return KEY_TIMEOUT;
108 sysadm 1.14 }
109 sysadm 1.21
110     if (FD_ISSET(STDIN_FILENO, &testfds))
111 sysadm 1.14 {
112 sysadm 1.26 flags = fcntl(STDIN_FILENO, F_GETFL, 0);
113     fcntl(socket_server, F_SETFL, flags | O_NONBLOCK);
114    
115 sysadm 1.22 len = read(STDIN_FILENO, buf, sizeof(buf));
116 sysadm 1.26 if (len < 0)
117     {
118     if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
119     {
120 sysadm 1.27 log_error("read(STDIN) error (%d)\n", errno);
121 sysadm 1.26 }
122     }
123 sysadm 1.27 else if (len == 0)
124     {
125     out = KEY_NULL; // broken pipe
126     }
127 sysadm 1.26
128 sysadm 1.21 pos = 0;
129 sysadm 1.26
130     fcntl(STDIN_FILENO, F_SETFL, flags);
131    
132 sysadm 1.21 break;
133 sysadm 1.14 }
134    
135     // For debug
136     // for (j = 0; j < len; j++)
137     // log_std ("<--[%u]\n", (buf[j] + 256) % 256);
138 sysadm 1.11 }
139 sysadm 1.14
140     while (pos < len)
141 sysadm 1.11 {
142 sysadm 1.18 unsigned char c = buf[pos++];
143 sysadm 1.5
144 sysadm 1.14 if (c == KEY_CONTROL)
145     {
146     if (in_control == 0)
147     {
148     in_control = 1;
149     i = 0;
150     continue;
151     }
152     }
153 sysadm 1.1
154 sysadm 1.14 if (in_control)
155     {
156     tmp[i++] = c;
157     if (i >= 2)
158     {
159     out = (int)tmp[0] * 256 + tmp[1];
160     in_control = 0;
161     break;
162     }
163     continue;
164     }
165 sysadm 1.6
166 sysadm 1.14 if (c == ESC_KEY)
167     {
168     if (in_esc == 0)
169     {
170     in_esc = 1;
171     in_ascii = 1;
172     i = 0;
173     continue;
174     }
175     else
176     {
177     out = ESC_KEY;
178     in_esc = 0;
179     break;
180     }
181     }
182 sysadm 1.3
183 sysadm 1.14 in_esc = 0;
184 sysadm 1.1
185 sysadm 1.14 if (in_ascii)
186     {
187     tmp[i++] = c;
188     if (c == 'm')
189     {
190     in_ascii = 0;
191     continue;
192     }
193     if (i == 2 && c >= 'A' && c <= 'D')
194     {
195     in_ascii = 0;
196     switch (c)
197     {
198     case 'A':
199     out = KEY_UP;
200     break;
201     case 'B':
202     out = KEY_DOWN;
203     break;
204     case 'C':
205     out = KEY_RIGHT;
206     break;
207     case 'D':
208     out = KEY_LEFT;
209     break;
210     }
211     break;
212     }
213     if (i == 3 && tmp[0] == 91 && tmp[2] == 126)
214     {
215     in_ascii = 0;
216     switch (tmp[1])
217     {
218     case 49:
219     out = KEY_HOME;
220     break;
221     case 51:
222     out = KEY_DEL;
223     break;
224     case 52:
225     out = KEY_END;
226     break;
227     case 53:
228     out = KEY_PGUP;
229     break;
230     case 54:
231     out = KEY_PGDN;
232     break;
233     }
234     break;
235     }
236     continue;
237     }
238 sysadm 1.1
239 sysadm 1.14 out = ((int)c + 256) % 256;
240     break;
241 sysadm 1.1 }
242    
243 sysadm 1.14 // for debug
244     // log_std ("-->[%u]\n", out);
245 sysadm 1.1
246 sysadm 1.14 return out;
247 sysadm 1.1 }
248 sysadm 1.5
249 sysadm 1.14 int igetch_t(long int sec)
250 sysadm 1.9 {
251 sysadm 1.14 int ch;
252     time_t t_begin = time(0);
253 sysadm 1.10
254 sysadm 1.14 do
255     {
256 sysadm 1.17 ch = igetch(0);
257 sysadm 1.25 } while (!SYS_server_exit && ch == KEY_TIMEOUT && (time(0) - t_begin < sec));
258 sysadm 1.9
259 sysadm 1.14 return ch;
260 sysadm 1.9 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1