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

Annotation of /lbbs/src/io.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.45 - (hide annotations)
Tue Jun 17 13:25:49 2025 UTC (8 months, 4 weeks ago) by sysadm
Branch: MAIN
Changes since 1.44: +12 -8 lines
Content type: text/x-csrc
Add conditional compile flag for debugging code

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

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