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

Annotation of /lbbs/src/io.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.47 - (hide annotations)
Sat Jun 21 02:15:18 2025 UTC (8 months, 3 weeks ago) by sysadm
Branch: MAIN
Changes since 1.46: +6 -6 lines
Content type: text/x-csrc
Re-order included order files

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 sysadm 1.47 #include "common.h"
18 sysadm 1.1 #include "io.h"
19 sysadm 1.16 #include "log.h"
20 sysadm 1.22 #include <errno.h>
21 sysadm 1.47 #include <fcntl.h>
22     #include <stdarg.h>
23 sysadm 1.1 #include <stdio.h>
24 sysadm 1.28 #include <string.h>
25 sysadm 1.9 #include <time.h>
26     #include <unistd.h>
27 sysadm 1.47 #include <sys/epoll.h>
28     #include <sys/ioctl.h>
29 sysadm 1.22 #include <sys/select.h>
30 sysadm 1.47 #include <libssh/callbacks.h>
31 sysadm 1.39 #include <libssh/libssh.h>
32     #include <libssh/server.h>
33 sysadm 1.1
34 sysadm 1.28 static char stdout_buf[BUFSIZ];
35     static int stdout_buf_len = 0;
36 sysadm 1.30 static int stdout_buf_offset = 0;
37 sysadm 1.1
38 sysadm 1.14 int prints(const char *format, ...)
39 sysadm 1.1 {
40 sysadm 1.28 char buf[BUFSIZ];
41 sysadm 1.14 va_list args;
42 sysadm 1.28 int ret;
43 sysadm 1.1
44 sysadm 1.14 va_start(args, format);
45 sysadm 1.28 ret = vsnprintf(buf, sizeof(buf), format, args);
46 sysadm 1.14 va_end(args);
47 sysadm 1.1
48 sysadm 1.30 if (ret > 0)
49 sysadm 1.28 {
50 sysadm 1.30 if (stdout_buf_len + ret > BUFSIZ)
51     {
52     iflush();
53     }
54 sysadm 1.31
55 sysadm 1.30 if (stdout_buf_len + ret <= BUFSIZ)
56     {
57     memcpy(stdout_buf + stdout_buf_len, buf, (size_t)ret);
58     stdout_buf_len += ret;
59     }
60     else
61     {
62     errno = EAGAIN;
63     ret = (BUFSIZ - stdout_buf_len - ret);
64 sysadm 1.35 log_error("Output buffer is full, additional %d is required\n", ret);
65 sysadm 1.30 }
66 sysadm 1.28 }
67 sysadm 1.30
68     return ret;
69     }
70    
71     int outc(char c)
72     {
73     int ret;
74    
75     if (stdout_buf_len + 1 > BUFSIZ)
76 sysadm 1.28 {
77 sysadm 1.30 iflush();
78     }
79    
80     if (stdout_buf_len + 1 <= BUFSIZ)
81     {
82     stdout_buf[stdout_buf_len] = c;
83     stdout_buf_len++;
84     }
85     else
86     {
87     errno = EAGAIN;
88     ret = -1;
89 sysadm 1.28 }
90    
91     return ret;
92 sysadm 1.1 }
93    
94 sysadm 1.43 int iflush(void)
95 sysadm 1.1 {
96 sysadm 1.28 int flags;
97 sysadm 1.29 struct epoll_event ev, events[MAX_EVENTS];
98     int nfds, epollfd;
99 sysadm 1.30 int retry;
100 sysadm 1.28 int ret = 0;
101    
102 sysadm 1.29 epollfd = epoll_create1(0);
103     if (epollfd < 0)
104     {
105     log_error("epoll_create1() error (%d)\n", errno);
106     return -1;
107     }
108    
109     ev.events = EPOLLOUT;
110     ev.data.fd = STDOUT_FILENO;
111     if (epoll_ctl(epollfd, EPOLL_CTL_ADD, STDOUT_FILENO, &ev) == -1)
112     {
113     log_error("epoll_ctl(STDOUT_FILENO) error (%d)\n", errno);
114 sysadm 1.31 if (close(epollfd) < 0)
115     {
116     log_error("close(epoll) error (%d)\n");
117     }
118 sysadm 1.29 return -1;
119     }
120    
121 sysadm 1.28 // Set STDOUT as non-blocking
122     flags = fcntl(STDOUT_FILENO, F_GETFL, 0);
123     fcntl(STDOUT_FILENO, F_SETFL, flags | O_NONBLOCK);
124    
125 sysadm 1.30 // Retry wait / flush for at most 3 times
126     retry = 3;
127     while (retry > 0 && !SYS_server_exit)
128 sysadm 1.28 {
129 sysadm 1.30 retry--;
130    
131 sysadm 1.29 nfds = epoll_wait(epollfd, events, MAX_EVENTS, 100); // 0.1 second
132 sysadm 1.28
133 sysadm 1.29 if (nfds < 0)
134 sysadm 1.28 {
135 sysadm 1.29 if (errno != EINTR)
136     {
137     log_error("epoll_wait() error (%d)\n", errno);
138     break;
139     }
140 sysadm 1.28 continue;
141     }
142 sysadm 1.29 else if (nfds == 0) // timeout
143 sysadm 1.28 {
144 sysadm 1.29 continue;
145 sysadm 1.28 }
146 sysadm 1.29
147     for (int i = 0; i < nfds; i++)
148 sysadm 1.28 {
149 sysadm 1.29 if (events[i].data.fd == STDOUT_FILENO)
150 sysadm 1.28 {
151 sysadm 1.30 while (stdout_buf_offset < stdout_buf_len && !SYS_server_exit) // write until complete or error
152 sysadm 1.28 {
153 sysadm 1.39 if (SSH_v2)
154     {
155     ret = ssh_channel_write(SSH_channel, stdout_buf + stdout_buf_offset, (uint32_t)(stdout_buf_len - stdout_buf_offset));
156     if (ret == SSH_ERROR)
157     {
158     log_error("ssh_channel_write() error: %s\n", ssh_get_error(SSH_session));
159     retry = 0;
160     break;
161     }
162     }
163     else
164     {
165     ret = (int)write(STDOUT_FILENO, stdout_buf + stdout_buf_offset, (size_t)(stdout_buf_len - stdout_buf_offset));
166     }
167 sysadm 1.29 if (ret < 0)
168     {
169     if (errno == EAGAIN || errno == EWOULDBLOCK)
170     {
171     break;
172     }
173     else if (errno == EINTR)
174     {
175     continue;
176     }
177     else
178     {
179 sysadm 1.46 #ifdef _DEBUG
180 sysadm 1.29 log_error("write(STDOUT) error (%d)\n", errno);
181 sysadm 1.46 #endif
182 sysadm 1.30 retry = 0;
183 sysadm 1.29 break;
184     }
185     }
186     else if (ret == 0) // broken pipe
187     {
188 sysadm 1.30 retry = 0;
189 sysadm 1.29 break;
190     }
191     else
192     {
193     stdout_buf_offset += ret;
194 sysadm 1.30 if (stdout_buf_offset >= stdout_buf_len) // flush buffer completely
195 sysadm 1.29 {
196     ret = 0;
197 sysadm 1.30 stdout_buf_offset = 0;
198 sysadm 1.29 stdout_buf_len = 0;
199 sysadm 1.30 retry = 0;
200 sysadm 1.29 break;
201     }
202     continue;
203     }
204 sysadm 1.28 }
205     }
206     }
207     }
208 sysadm 1.6
209 sysadm 1.28 // Restore STDOUT flags
210     fcntl(STDOUT_FILENO, F_SETFL, flags);
211 sysadm 1.6
212 sysadm 1.31 if (close(epollfd) < 0)
213     {
214     log_error("close(epoll) error (%d)\n");
215     }
216    
217 sysadm 1.28 return ret;
218 sysadm 1.1 }
219    
220 sysadm 1.31 int igetch(int timeout)
221 sysadm 1.1 {
222 sysadm 1.18 // static input buffer
223 sysadm 1.22 static unsigned char buf[LINE_BUFFER_LEN];
224 sysadm 1.31 static int len = 0;
225 sysadm 1.18 static int pos = 0;
226    
227 sysadm 1.29 struct epoll_event ev, events[MAX_EVENTS];
228     int nfds, epollfd;
229 sysadm 1.31 int ret;
230     int loop;
231 sysadm 1.21
232 sysadm 1.22 unsigned char tmp[LINE_BUFFER_LEN];
233 sysadm 1.31 int out = KEY_NULL;
234 sysadm 1.18 int in_esc = 0;
235     int in_ascii = 0;
236     int in_control = 0;
237     int i = 0;
238 sysadm 1.26 int flags;
239 sysadm 1.1
240 sysadm 1.29 epollfd = epoll_create1(0);
241     if (epollfd < 0)
242     {
243     log_error("epoll_create1() error (%d)\n", errno);
244     return -1;
245     }
246    
247     ev.events = EPOLLIN;
248     ev.data.fd = STDIN_FILENO;
249     if (epoll_ctl(epollfd, EPOLL_CTL_ADD, STDIN_FILENO, &ev) == -1)
250 sysadm 1.14 {
251 sysadm 1.29 log_error("epoll_ctl(STDIN_FILENO) error (%d)\n", errno);
252 sysadm 1.31
253     if (close(epollfd) < 0)
254     {
255     log_error("close(epoll) error (%d)\n");
256     }
257 sysadm 1.29 return -1;
258     }
259 sysadm 1.9
260 sysadm 1.29 flags = fcntl(STDIN_FILENO, F_GETFL, 0);
261     fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
262 sysadm 1.9
263 sysadm 1.31 loop = 1;
264    
265     while (loop && pos >= len && !SYS_server_exit)
266 sysadm 1.29 {
267 sysadm 1.31 len = 0;
268     pos = 0;
269    
270 sysadm 1.39 if (SSH_v2 && ssh_channel_is_closed(SSH_channel))
271     {
272     log_error("SSH channel is closed\n");
273     loop = 0;
274     break;
275     }
276    
277 sysadm 1.31 nfds = epoll_wait(epollfd, events, MAX_EVENTS, timeout);
278 sysadm 1.9
279 sysadm 1.29 if (nfds < 0)
280 sysadm 1.14 {
281 sysadm 1.21 if (errno != EINTR)
282     {
283 sysadm 1.29 log_error("epoll_wait() error (%d)\n", errno);
284 sysadm 1.31 break;
285 sysadm 1.21 }
286     continue;
287 sysadm 1.14 }
288 sysadm 1.31 else if (nfds == 0) // timeout
289 sysadm 1.14 {
290 sysadm 1.31 out = KEY_TIMEOUT;
291     break;
292 sysadm 1.14 }
293 sysadm 1.21
294 sysadm 1.29 for (int i = 0; i < nfds; i++)
295 sysadm 1.14 {
296 sysadm 1.29 if (events[i].data.fd == STDIN_FILENO)
297 sysadm 1.26 {
298 sysadm 1.31 while (len < sizeof(buf) && !SYS_server_exit) // read until complete or error
299 sysadm 1.26 {
300 sysadm 1.39 if (SSH_v2)
301     {
302     ret = ssh_channel_read_nonblocking(SSH_channel, buf + len, sizeof(buf) - (uint32_t)len, 0);
303     if (ret == SSH_ERROR)
304     {
305     log_error("ssh_channel_read_nonblocking() error: %s\n", ssh_get_error(SSH_session));
306     loop = 0;
307     break;
308     }
309     else if (ret == SSH_EOF)
310     {
311     loop = 0;
312     break;
313     }
314     else if (ret == 0)
315     {
316 sysadm 1.40 out = 0;
317 sysadm 1.39 break; // Check whether channel is still open
318     }
319     }
320     else
321     {
322     ret = (int)read(STDIN_FILENO, buf + len, sizeof(buf) - (size_t)len);
323     }
324 sysadm 1.31 if (ret < 0)
325 sysadm 1.29 {
326     if (errno == EAGAIN || errno == EWOULDBLOCK)
327     {
328 sysadm 1.32 out = 0;
329 sysadm 1.31 loop = 0;
330     break;
331 sysadm 1.29 }
332     else if (errno == EINTR)
333     {
334     continue;
335     }
336     else
337     {
338 sysadm 1.46 #ifdef _DEBUG
339 sysadm 1.29 log_error("read(STDIN) error (%d)\n", errno);
340 sysadm 1.46 #endif
341 sysadm 1.31 loop = 0;
342     break;
343 sysadm 1.29 }
344     }
345 sysadm 1.31 else if (ret == 0) // broken pipe
346 sysadm 1.29 {
347 sysadm 1.31 loop = 0;
348     break;
349     }
350     else
351     {
352     len += ret;
353     continue;
354 sysadm 1.29 }
355 sysadm 1.26 }
356     }
357 sysadm 1.14 }
358    
359     // For debug
360 sysadm 1.45 #ifdef _DEBUG
361     for (int j = pos; j < len; j++)
362     {
363     log_common("Debug: <--[%u]\n", (buf[j] + 256) % 256);
364     }
365     #endif
366 sysadm 1.11 }
367 sysadm 1.14
368 sysadm 1.29 fcntl(STDIN_FILENO, F_SETFL, flags);
369    
370 sysadm 1.14 while (pos < len)
371 sysadm 1.11 {
372 sysadm 1.18 unsigned char c = buf[pos++];
373 sysadm 1.5
374 sysadm 1.14 if (c == KEY_CONTROL)
375     {
376     if (in_control == 0)
377     {
378     in_control = 1;
379     i = 0;
380     continue;
381     }
382     }
383 sysadm 1.1
384 sysadm 1.14 if (in_control)
385     {
386     tmp[i++] = c;
387     if (i >= 2)
388     {
389     out = (int)tmp[0] * 256 + tmp[1];
390     in_control = 0;
391     break;
392     }
393     continue;
394     }
395 sysadm 1.6
396 sysadm 1.37 if (c == KEY_ESC)
397 sysadm 1.14 {
398     if (in_esc == 0)
399     {
400     in_esc = 1;
401     in_ascii = 1;
402     i = 0;
403     continue;
404     }
405     else
406     {
407 sysadm 1.37 out = KEY_CSI;
408 sysadm 1.14 in_esc = 0;
409     break;
410     }
411     }
412 sysadm 1.3
413 sysadm 1.14 in_esc = 0;
414 sysadm 1.1
415 sysadm 1.14 if (in_ascii)
416     {
417     tmp[i++] = c;
418 sysadm 1.33 if (i == 2 && (tmp[0] == 79 || tmp[0] == 91))
419 sysadm 1.14 {
420     in_ascii = 0;
421 sysadm 1.33 switch (tmp[1])
422 sysadm 1.14 {
423 sysadm 1.33 case 65:
424 sysadm 1.14 out = KEY_UP;
425     break;
426 sysadm 1.33 case 66:
427 sysadm 1.14 out = KEY_DOWN;
428     break;
429 sysadm 1.33 case 67:
430 sysadm 1.14 out = KEY_RIGHT;
431     break;
432 sysadm 1.33 case 68:
433 sysadm 1.14 out = KEY_LEFT;
434     break;
435 sysadm 1.33 default:
436     in_ascii = 1;
437     }
438     if (!in_ascii)
439     {
440     break;
441     }
442     }
443     if (i == 2 && tmp[0] == 91) // Fterm
444     {
445     in_ascii = 0;
446     switch (tmp[1])
447     {
448     case 86:
449     out = KEY_SHIFT_F1;
450     break;
451     case 90:
452     out = KEY_SHIFT_F2;
453     break;
454     case 97:
455     out = KEY_SHIFT_F3;
456     break;
457     case 98:
458     out = KEY_SHIFT_F4;
459     break;
460     case 99:
461     out = KEY_SHIFT_F5;
462     break;
463     case 100:
464     out = KEY_SHIFT_F6;
465     break;
466     case 101:
467     out = KEY_SHIFT_F7;
468     break;
469     case 102:
470     out = KEY_SHIFT_F8;
471     break;
472     case 103:
473     out = KEY_SHIFT_F9;
474     break;
475     case 104:
476     out = KEY_SHIFT_F10;
477     break;
478     case 107:
479     out = KEY_CTRL_F1;
480     break;
481     case 108:
482     out = KEY_CTRL_F2;
483     break;
484     case 109:
485     out = KEY_CTRL_F3;
486     break;
487     case 112:
488     out = KEY_CTRL_F6;
489     break;
490     case 113:
491     out = KEY_CTRL_F7;
492     break;
493     case 114:
494     out = KEY_CTRL_F8;
495     break;
496     case 115:
497     out = KEY_CTRL_F9;
498     break;
499     case 116:
500     out = KEY_CTRL_F10;
501     break;
502     default:
503     in_ascii = 1;
504     }
505     if (!in_ascii)
506     {
507     break;
508     }
509     }
510     if (i == 2 && tmp[0] == 79) // Xterm
511     {
512     in_ascii = 0;
513     switch (tmp[1])
514     {
515     case 80:
516     out = KEY_F1;
517     break;
518     case 81:
519     out = KEY_F2;
520     break;
521     case 82:
522     out = KEY_F3;
523     break;
524     case 83:
525     out = KEY_F4;
526     break;
527     default:
528     in_ascii = 1;
529     }
530     if (!in_ascii)
531     {
532     break;
533 sysadm 1.14 }
534     }
535     if (i == 3 && tmp[0] == 91 && tmp[2] == 126)
536     {
537     in_ascii = 0;
538     switch (tmp[1])
539     {
540     case 49:
541     out = KEY_HOME;
542     break;
543 sysadm 1.42 case 50:
544     out = KEY_INS;
545     break;
546 sysadm 1.14 case 51:
547     out = KEY_DEL;
548     break;
549     case 52:
550     out = KEY_END;
551     break;
552     case 53:
553     out = KEY_PGUP;
554     break;
555     case 54:
556     out = KEY_PGDN;
557     break;
558 sysadm 1.33 default:
559     in_ascii = 1;
560     }
561     if (!in_ascii)
562     {
563     break;
564     }
565     }
566 sysadm 1.39 if (i == 4 && tmp[0] == 91 && tmp[1] == 49 && tmp[3] == 126) // Fterm
567 sysadm 1.33 {
568     in_ascii = 0;
569     switch (tmp[2])
570     {
571     case 49:
572     out = KEY_F1;
573     break;
574     case 50:
575     out = KEY_F2;
576     break;
577     case 51:
578     out = KEY_F3;
579     break;
580     case 52:
581     out = KEY_F4;
582     break;
583     case 53:
584     out = KEY_F5;
585     break;
586     case 55:
587     out = KEY_F6;
588     break;
589     case 56:
590     out = KEY_F7;
591     break;
592     case 57:
593     out = KEY_F8;
594     break;
595     default:
596     in_ascii = 1;
597     }
598     if (!in_ascii)
599     {
600     break;
601     }
602     }
603     if (i == 4 && tmp[0] == 91 && tmp[1] == 50 && tmp[3] == 126) // Fterm
604     {
605     in_ascii = 0;
606     switch (tmp[2])
607     {
608     case 48:
609     out = KEY_F9;
610     break;
611     case 49:
612     out = KEY_F10;
613     break;
614     case 50:
615     out = KEY_F11; // Fterm
616     break;
617     case 51:
618     out = KEY_F11; // Xterm
619     break;
620     case 52:
621     out = KEY_F12; // Xterm
622     break;
623     default:
624     in_ascii = 1;
625     }
626     if (!in_ascii)
627     {
628     break;
629     }
630     }
631     if (i == 5 && tmp[0] == 91 && tmp[1] == 49 && tmp[2] == 59 && tmp[3] == 53) // Xterm
632     {
633     in_ascii = 0;
634     switch (tmp[4])
635     {
636 sysadm 1.41 case 65:
637     out = KEY_CTRL_UP;
638     break;
639     case 66:
640     out = KEY_CTRL_DOWN;
641     break;
642     case 67:
643     out = KEY_CTRL_RIGHT;
644     break;
645     case 68:
646     out = KEY_CTRL_LEFT;
647     break;
648     case 70:
649     out = KEY_CTRL_END;
650     break;
651     case 72:
652     out = KEY_CTRL_HOME;
653     break;
654 sysadm 1.33 case 80:
655     out = KEY_CTRL_F1;
656     break;
657     case 81:
658     out = KEY_CTRL_F2;
659     break;
660     case 82:
661     out = KEY_CTRL_F3;
662     break;
663     default:
664     in_ascii = 1;
665     }
666     if (!in_ascii)
667     {
668     break;
669     }
670     }
671     if (i == 6 && tmp[0] == 91 && tmp[1] == 49 && tmp[3] == 59 && tmp[4] == 53 && tmp[5] == 126) // Xterm
672     {
673     in_ascii = 0;
674     switch (tmp[2])
675     {
676     case 53:
677     out = KEY_CTRL_F5;
678     break;
679     case 55:
680     out = KEY_CTRL_F6;
681     break;
682     case 56:
683     out = KEY_CTRL_F7;
684     break;
685     case 57:
686     out = KEY_CTRL_F8;
687     break;
688     default:
689     in_ascii = 1;
690     }
691     if (!in_ascii)
692     {
693     break;
694     }
695     }
696     if (i == 6 && tmp[0] == 91 && tmp[1] == 50 && tmp[3] == 59 && tmp[4] == 53 && tmp[5] == 126) // Xterm
697     {
698     in_ascii = 0;
699     switch (tmp[2])
700     {
701     case 48:
702     out = KEY_CTRL_F9;
703     break;
704     case 49:
705     out = KEY_CTRL_F10;
706     break;
707     case 51:
708     out = KEY_CTRL_F11;
709     break;
710     case 52:
711     out = KEY_CTRL_F12;
712     break;
713     default:
714     in_ascii = 1;
715     }
716     if (!in_ascii)
717     {
718     break;
719     }
720     }
721     if (i == 5 && tmp[0] == 91 && tmp[1] == 49 && tmp[2] == 59 && tmp[3] == 50) // Xterm
722     {
723     in_ascii = 0;
724     switch (tmp[4])
725     {
726     case 80:
727     out = KEY_SHIFT_F1;
728     break;
729     case 81:
730     out = KEY_SHIFT_F2;
731     break;
732     case 82:
733     out = KEY_SHIFT_F3;
734     break;
735     case 83:
736     out = KEY_SHIFT_F4;
737     break;
738     default:
739     in_ascii = 1;
740     }
741     if (!in_ascii)
742     {
743     break;
744 sysadm 1.14 }
745 sysadm 1.33 }
746     if (i == 6 && tmp[0] == 91 && tmp[1] == 49 && tmp[3] == 59 && tmp[4] == 50 && tmp[5] == 126) // Xterm
747     {
748     in_ascii = 0;
749     switch (tmp[2])
750     {
751     case 53:
752     out = KEY_SHIFT_F5;
753     break;
754     case 55:
755     out = KEY_SHIFT_F6;
756     break;
757     case 56:
758     out = KEY_SHIFT_F7;
759     break;
760     case 57:
761     out = KEY_SHIFT_F8;
762     break;
763     default:
764     in_ascii = 1;
765     }
766     if (!in_ascii)
767     {
768     break;
769     }
770     }
771     if (i == 6 && tmp[0] == 91 && tmp[1] == 50 && tmp[3] == 59 && tmp[4] == 50 && tmp[5] == 126) // Xterm
772     {
773     in_ascii = 0;
774     switch (tmp[2])
775     {
776     case 48:
777     out = KEY_SHIFT_F9;
778     break;
779     case 49:
780     out = KEY_SHIFT_F10;
781     break;
782     case 51:
783     out = KEY_SHIFT_F11;
784     break;
785     case 52:
786     out = KEY_SHIFT_F12;
787     break;
788     default:
789     in_ascii = 1;
790     }
791     if (!in_ascii)
792     {
793     break;
794     }
795     }
796    
797     if (c == 'm')
798     {
799     in_ascii = 0;
800 sysadm 1.14 }
801     continue;
802     }
803 sysadm 1.1
804 sysadm 1.14 out = ((int)c + 256) % 256;
805     break;
806 sysadm 1.1 }
807    
808 sysadm 1.31 if (close(epollfd) < 0)
809     {
810     log_error("close(epoll) error (%d)\n");
811     }
812    
813 sysadm 1.36 // For ESC key
814     if (out == 0 && in_esc)
815     {
816     out = KEY_ESC;
817     }
818    
819 sysadm 1.33 // for debug
820 sysadm 1.45 #ifdef _DEBUG
821     if (out != KEY_TIMEOUT && out != KEY_NULL)
822     {
823     log_common("Debug: -->[0x %x]\n", out);
824     }
825     #endif
826 sysadm 1.33
827 sysadm 1.14 return out;
828 sysadm 1.1 }
829 sysadm 1.5
830 sysadm 1.31 int igetch_t(int sec)
831 sysadm 1.9 {
832 sysadm 1.14 int ch;
833 sysadm 1.44 time_t t_begin = time(NULL);
834 sysadm 1.10
835 sysadm 1.14 do
836     {
837 sysadm 1.31 ch = igetch(100);
838 sysadm 1.44 } while (!SYS_server_exit && ch == KEY_TIMEOUT && (time(NULL) - t_begin < sec));
839 sysadm 1.9
840 sysadm 1.14 return ch;
841 sysadm 1.9 }
842 sysadm 1.31
843     void igetch_reset()
844     {
845     int ch;
846     do
847     {
848     ch = igetch(0);
849     } while (ch != KEY_NULL && ch != KEY_TIMEOUT);
850     }

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