X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fconsole-io.c;h=e3807feca84a350bb2ca7540e4f8752bf02e274d;hb=b50dc8d84850e0452a7a4d742ed0a0fa46fe491e;hp=0e491d6dfaf8edb6580091240be976f2609ca7f3;hpb=096265478e6e4145c90250a5bf78c0c179ee50af;p=mono.git diff --git a/mono/metadata/console-io.c b/mono/metadata/console-io.c index 0e491d6dfaf..e3807feca84 100644 --- a/mono/metadata/console-io.c +++ b/mono/metadata/console-io.c @@ -16,6 +16,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include /* On solaris, curses.h must come before both termios.h and term.h */ #ifdef HAVE_CURSES_H #include @@ -71,7 +77,7 @@ ves_icall_System_ConsoleDriver_InternalKeyAvailable (gint32 timeout) } MonoBoolean -ves_icall_System_ConsoleDriver_TtySetup (MonoString *teardown) +ves_icall_System_ConsoleDriver_TtySetup (MonoString *teardown, char *verase, char *vsusp, char *intr) { return FALSE; } @@ -186,19 +192,74 @@ tty_teardown (void) tcflush (STDIN_FILENO, TCIFLUSH); tcsetattr (STDIN_FILENO, TCSANOW, &initial_attr); + set_property (ECHO, TRUE); setup_finished = FALSE; } +static void +do_console_cancel_event (void) +{ + static MonoClassField *cancel_handler_field; + MonoDomain *domain = mono_domain_get (); + MonoClass *klass; + MonoDelegate *load_value; + MonoMethod *method; + MonoMethodMessage *msg; + MonoMethod *im; + + if (!domain->domain) + return; + + klass = mono_class_from_name (mono_defaults.corlib, "System", "Console"); + if (klass == NULL) + return; + + if (cancel_handler_field == NULL) { + cancel_handler_field = mono_class_get_field_from_name (klass, "cancel_handler"); + g_assert (cancel_handler_field); + } + + mono_field_static_get_value (mono_class_vtable (domain, klass), cancel_handler_field, &load_value); + if (load_value == NULL) + return; + + klass = load_value->object.vtable->klass; + method = mono_class_get_method_from_name (klass, "BeginInvoke", -1); + g_assert (method != NULL); + im = mono_get_delegate_invoke (method->klass); + msg = mono_method_call_message_new (method, NULL, im, NULL, NULL); + mono_thread_pool_add ((MonoObject *) load_value, msg, NULL, NULL); +} + +static gboolean in_sigint; +static void +sigint_handler (int signo) +{ + MONO_ARCH_SAVE_REGS; + + if (in_sigint) + return; + + in_sigint = TRUE; + do_console_cancel_event (); + in_sigint = FALSE; +} + MonoBoolean -ves_icall_System_ConsoleDriver_TtySetup (MonoString *teardown) +ves_icall_System_ConsoleDriver_TtySetup (MonoString *teardown, char *verase, char *vsusp, char*intr) { struct termios attr; MONO_ARCH_SAVE_REGS; + + *verase = '\0'; + *vsusp = '\0'; + *intr = '\0'; if (tcgetattr (STDIN_FILENO, &initial_attr) == -1) return FALSE; + /* TODO: handle SIGTSTP - Ctrl-Z */ attr = initial_attr; attr.c_lflag &= ~ICANON; attr.c_cc [VMIN] = 1; @@ -206,6 +267,14 @@ ves_icall_System_ConsoleDriver_TtySetup (MonoString *teardown) if (tcsetattr (STDIN_FILENO, TCSANOW, &attr) == -1) return FALSE; + *verase = initial_attr.c_cc [VERASE]; + *vsusp = initial_attr.c_cc [VSUSP]; + *intr = initial_attr.c_cc [VINTR]; + /* If initialized from another appdomain... */ + if (setup_finished) + return TRUE; + + signal (SIGINT, sigint_handler); setup_finished = TRUE; if (!atexit_called) { if (teardown != NULL) @@ -224,6 +293,8 @@ ves_icall_System_ConsoleDriver_GetTtySize (HANDLE handle, gint32 *width, gint32 struct winsize ws; int res; + MONO_ARCH_SAVE_REGS; + res = ioctl (GPOINTER_TO_INT (handle), TIOCGWINSZ, &ws); if (!res) {