00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <setjmp.h>
00016 #include <signal.h>
00017 #ifndef WIN32
00018 #include <unistd.h>
00019 #include <string.h>
00020 #else
00021 #include "win32.h"
00022 #endif
00023
00024 #include "kbdtermio.h"
00025 #include "kbdterm.h"
00026 #include "sic_comm.h"
00027 #include "gag_trace.h"
00028
00029 #if defined(linux) || defined(darwin)
00030
00031 #define JMP_BUF sigjmp_buf
00032 #define SET_JMP( tag) sigsetjmp( tag, 1)
00033 #define LONG_JMP( tag) siglongjmp( tag, 1)
00034 #elif defined(WIN32)
00035 #define JMP_BUF jmp_buf
00036 #define SET_JMP( tag) setjmp( tag)
00037 #define LONG_JMP( tag) longjmp( tag, 1)
00038 #else
00039 #define JMP_BUF jmp_buf
00040 #define SET_JMP( tag) setjmp( tag)
00041 #define LONG_JMP( tag) longjmp( tag, 1)
00042 #endif
00043
00044 static JMP_BUF place_for_continue;
00045 static int yesisatty = 0;
00046 static command_line_t s_command_line;
00047
00048 static void quit( int sig_num)
00049 {
00050 gag_trace( "<trace: signal> quit on %d", sig_num);
00051 if (yesisatty) {
00052 reset_termio( );
00053 }
00054 sic_do_exit( 1);
00055 }
00056
00057 static void do_continue( )
00058 {
00059 fflush( NULL);
00060 if (yesisatty) {
00061 reset_termio( );
00062 }
00063 LONG_JMP( place_for_continue);
00064 }
00065
00066 static void redraw_prompt( command_line_t *command_line)
00067 {
00068 gag_trace( "<trace: listener> redraw_prompt");
00069 if (yesisatty) {
00070 s_command_line = *command_line;
00071 reset_kbd_line( command_line->prompt, command_line->line, &command_line->code);
00072 }
00073 }
00074
00075 static void on_continue( int sig_num)
00076 {
00077 gag_trace( "<trace: signal> on_continue on %d", sig_num);
00078 signal( sig_num, on_continue);
00079 do_continue( );
00080 }
00081
00082 static void read_keyboard( command_line_t * command_line)
00083 {
00084 if (yesisatty) {
00085 command_line->nc = kbd_line( command_line->prompt, command_line->line, &command_line->code);
00086 } else {
00087 size_t l;
00088
00089 command_line->prompt[0] = '\0';
00090 if ((fgets( command_line->line, MAXBUF, stdin)) == NULL)
00091 strcpy( command_line->line, "SIC\\EXIT\n");
00092
00093 l = strlen( command_line->line);
00094
00095 if (l > 0 && command_line->line[l - 1] == '\n')
00096 l--;
00097 command_line->nc = l;
00098 command_line->code = 0;
00099 }
00100 }
00101
00102 static void keyboard_loop( )
00103 {
00104 while (1) {
00105 SET_JMP( place_for_continue);
00106
00107 if (sic_wait_prompt( &s_command_line, 500) == -1) {
00108
00109 sic_wait_prompt( &s_command_line, -1);
00110 }
00111
00112 SET_JMP( place_for_continue);
00113
00114 read_keyboard( &s_command_line);
00115
00116 sic_post_command_from_prompt( &s_command_line);
00117 }
00118 }
00119
00120 int run_keyboard( )
00121 {
00122
00123 #ifndef WIN32
00124 signal( SIGCONT, on_continue);
00125 signal( SIGSTOP, quit);
00126 #endif
00127 signal( SIGTERM, quit);
00128 signal( SIGSEGV, quit);
00129 signal( SIGABRT, quit);
00130 signal( SIGILL, quit);
00131
00132 sic_add_redraw_prompt_listener( redraw_prompt);
00133
00134
00135 yesisatty = isatty( STDIN_FILENO);
00136
00137 keyboard_loop( );
00138
00139 return 0;
00140 }
00141