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

Contents of /lbbs/src/io.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.26 - (show annotations)
Sun May 11 04:09:08 2025 UTC (10 months ago) by sysadm
Branch: MAIN
Changes since 1.25: +16 -1 lines
Content type: text/x-csrc
Change getch to non-blocking
Refine select parameter
Remove sleep

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

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