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

Contents of /lbbs/src/io.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.22 - (show annotations)
Sat May 10 02:14:46 2025 UTC (10 months, 1 week ago) by sysadm
Branch: MAIN
Changes since 1.21: +7 -6 lines
Content type: text/x-csrc
Refine to prevent blocking while shutdown server

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
77 if (clear_buf)
78 {
79 pos = 0;
80 len = 0;
81
82 return 0;
83 }
84
85 while (!SYS_server_exit && pos >= len)
86 {
87 FD_ZERO(&testfds);
88 FD_SET(STDIN_FILENO, &testfds);
89
90 timeout.tv_sec = 0;
91 timeout.tv_usec = 100 * 1000; // 0.1 second
92
93 ret = select(FD_SETSIZE, &testfds, NULL, NULL, &timeout);
94
95 if (ret < 0)
96 {
97 if (errno != EINTR)
98 {
99 log_error("Select error in igetch: !\n", errno);
100 return KEY_NULL;
101 }
102 continue;
103 }
104 else if (ret == 0)
105 {
106 return KEY_TIMEOUT;
107 }
108
109 if (FD_ISSET(STDIN_FILENO, &testfds))
110 {
111 len = read(STDIN_FILENO, buf, sizeof(buf));
112 pos = 0;
113 break;
114 }
115
116 // For debug
117 // for (j = 0; j < len; j++)
118 // log_std ("<--[%u]\n", (buf[j] + 256) % 256);
119 }
120
121 while (pos < len)
122 {
123 unsigned char c = buf[pos++];
124
125 if (c == '\0')
126 {
127 out = c;
128 break;
129 }
130
131 if (c == KEY_CONTROL)
132 {
133 if (in_control == 0)
134 {
135 in_control = 1;
136 i = 0;
137 continue;
138 }
139 }
140
141 if (in_control)
142 {
143 tmp[i++] = c;
144 if (i >= 2)
145 {
146 out = (int)tmp[0] * 256 + tmp[1];
147 in_control = 0;
148 break;
149 }
150 continue;
151 }
152
153 if (c == ESC_KEY)
154 {
155 if (in_esc == 0)
156 {
157 in_esc = 1;
158 in_ascii = 1;
159 i = 0;
160 continue;
161 }
162 else
163 {
164 out = ESC_KEY;
165 in_esc = 0;
166 break;
167 }
168 }
169
170 in_esc = 0;
171
172 if (in_ascii)
173 {
174 tmp[i++] = c;
175 if (c == 'm')
176 {
177 in_ascii = 0;
178 continue;
179 }
180 if (i == 2 && c >= 'A' && c <= 'D')
181 {
182 in_ascii = 0;
183 switch (c)
184 {
185 case 'A':
186 out = KEY_UP;
187 break;
188 case 'B':
189 out = KEY_DOWN;
190 break;
191 case 'C':
192 out = KEY_RIGHT;
193 break;
194 case 'D':
195 out = KEY_LEFT;
196 break;
197 }
198 break;
199 }
200 if (i == 3 && tmp[0] == 91 && tmp[2] == 126)
201 {
202 in_ascii = 0;
203 switch (tmp[1])
204 {
205 case 49:
206 out = KEY_HOME;
207 break;
208 case 51:
209 out = KEY_DEL;
210 break;
211 case 52:
212 out = KEY_END;
213 break;
214 case 53:
215 out = KEY_PGUP;
216 break;
217 case 54:
218 out = KEY_PGDN;
219 break;
220 }
221 break;
222 }
223 continue;
224 }
225
226 out = ((int)c + 256) % 256;
227 break;
228 }
229
230 // for debug
231 // log_std ("-->[%u]\n", out);
232
233 return out;
234 }
235
236 int igetch_t(long int sec)
237 {
238 int ch;
239 time_t t_begin = time(0);
240
241 do
242 {
243 ch = igetch(0);
244 } while ((ch == KEY_TIMEOUT || ch == 0xa) && (time(0) - t_begin < sec));
245
246 return ch;
247 }

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