*
* Copyright (C) 2005-2009 Novell, Inc. (http://www.novell.com)
*/
+#if defined(__native_client__)
+#include "console-null.c"
+#else
#include <config.h>
#include <glib.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <mono/metadata/object-internals.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/domain-internals.h>
+#include <mono/metadata/gc-internal.h>
#include <mono/metadata/metadata.h>
#include <mono/metadata/threadpool.h>
+#include <mono/utils/mono-signal-handler.h>
/* On solaris, curses.h must come before both termios.h and term.h */
#ifdef HAVE_CURSES_H
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
#endif
-#ifndef TIOCGWINSZ
-# ifdef HAVE_SYS_IOCTL_H
-# include <sys/ioctl.h>
-# endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
#endif
#include <mono/metadata/console-io.h>
static struct termios mono_attr;
#endif
+/* static void console_restore_signal_handlers (void); */
+static void console_set_signal_handlers (void);
+
void
mono_console_init (void)
{
terminal_get_dimensions (void)
{
struct winsize ws;
-
- if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) == 0)
- return (ws.ws_col << 16) | ws.ws_row;
-
+ int ret;
+ int save_errno = errno;
+
+ if (ioctl (STDIN_FILENO, TIOCGWINSZ, &ws) == 0){
+ ret = (ws.ws_col << 16) | ws.ws_row;
+ errno = save_errno;
+ return ret;
+ }
return -1;
}
#else
static void
tty_teardown (void)
{
+ int unused;
+
MONO_ARCH_SAVE_REGS;
if (!setup_finished)
return;
if (teardown_str != NULL) {
- write (STDOUT_FILENO, teardown_str, strlen (teardown_str));
+ unused = write (STDOUT_FILENO, teardown_str, strlen (teardown_str));
g_free (teardown_str);
teardown_str = NULL;
}
MonoMethod *method;
MonoMethodMessage *msg;
MonoMethod *im;
+ MonoVTable *vtable;
+ /* FIXME: this should likely iterate all the domains, instead */
if (!domain->domain)
return;
g_assert (cancel_handler_field);
}
- mono_field_static_get_value (mono_class_vtable (domain, klass), cancel_handler_field, &load_value);
+ vtable = mono_class_vtable_full (domain, klass, FALSE);
+ if (vtable == NULL)
+ return;
+ mono_field_static_get_value (vtable, cancel_handler_field, &load_value);
if (load_value == NULL)
return;
mono_thread_pool_add ((MonoObject *) load_value, msg, NULL, NULL);
}
+static int need_cancel = FALSE;
+/* this is executed from the finalizer thread */
+void
+mono_console_handle_async_ops (void)
+{
+ if (need_cancel) {
+ need_cancel = FALSE;
+ do_console_cancel_event ();
+ }
+}
+
static gboolean in_sigint;
-static void
-sigint_handler (int signo)
+
+MONO_SIGNAL_HANDLER_FUNC (static, sigint_handler, (int signo))
{
+ int save_errno;
MONO_ARCH_SAVE_REGS;
if (in_sigint)
return;
in_sigint = TRUE;
- do_console_cancel_event ();
+ save_errno = errno;
+ need_cancel = TRUE;
+ mono_gc_finalize_notify ();
+ errno = save_errno;
in_sigint = FALSE;
}
static struct sigaction save_sigcont, save_sigint, save_sigwinch;
-static void
-sigcont_handler (int signo, void *the_siginfo, void *data)
+MONO_SIGNAL_HANDLER_FUNC (static, sigcont_handler, (int signo, void *the_siginfo, void *data))
{
+ int unused;
// Ignore error, there is not much we can do in the sigcont handler.
tcsetattr (STDIN_FILENO, TCSANOW, &mono_attr);
if (keypad_xmit_str != NULL)
- write (STDOUT_FILENO, keypad_xmit_str, strlen (keypad_xmit_str));
+ unused = write (STDOUT_FILENO, keypad_xmit_str, strlen (keypad_xmit_str));
// Call previous handler
if (save_sigcont.sa_sigaction != NULL &&
(*save_sigcont.sa_sigaction) (signo, the_siginfo, data);
}
-static void
-sigwinch_handler (int signo, void *the_siginfo, void *data)
+MONO_SIGNAL_HANDLER_FUNC (static, sigwinch_handler, (int signo, void *the_siginfo, void *data))
{
int dims = terminal_get_dimensions ();
if (dims != -1)
(*save_sigwinch.sa_sigaction) (signo, the_siginfo, data);
}
-void
+/*
+ * console_set_signal_handlers:
+ *
+ * Installs various signals handlers for the use of the console, as
+ * follows:
+ *
+ * SIGCONT: this is received after the application has resumed execution
+ * if it was suspended with Control-Z before. This signal handler needs
+ * to resend the terminal sequence to send keyboard in keypad mode (this
+ * is the difference between getting a cuu1 code or a kcuu1 code for up-arrow
+ * for example
+ *
+ * SIGINT: invokes the System.Console.DoConsoleCancelEvent method using
+ * a thread from the thread pool which notifies all registered cancel_event
+ * listeners.
+ *
+ * SIGWINCH: is used to track changes to the console window when a GUI
+ * terminal is resized. It sets an internal variable that is checked
+ * by System.Console when the Terminfo driver has been activated.
+ */
+static void
console_set_signal_handlers ()
{
struct sigaction sigcont, sigint, sigwinch;
sigaction (SIGCONT, &sigcont, &save_sigcont);
// Interrupt handler
- sigint.sa_handler = sigint_handler;
+ sigint.sa_handler = (void *) sigint_handler;
sigint.sa_flags = 0;
sigemptyset (&sigint.sa_mask);
sigaction (SIGINT, &sigint, &save_sigint);
sigaction (SIGWINCH, &sigwinch, &save_sigwinch);
}
+#if currently_unuused
//
// Currently unused, should we ever call the restore handler?
// Perhaps before calling into Process.Start?
sigaction (SIGINT, &save_sigint, NULL);
sigaction (SIGWINCH, &save_sigwinch, NULL);
}
+#endif
static void
set_control_chars (MonoArray *control_chars, const guchar *cc)
if (dims == -1){
int cols = 0, rows = 0;
- char *str = getenv ("COLUMNS");
+ const char *str = g_getenv ("COLUMNS");
if (str != NULL)
cols = atoi (str);
- str = getenv ("LINES");
+ str = g_getenv ("LINES");
if (str != NULL)
rows = atoi (str);
/* 17 is the number of entries set in set_control_chars() above.
* NCCS is the total size, but, by now, we only care about those 17 values*/
- *control_chars = mono_array_new (mono_domain_get (), mono_defaults.byte_class, 17);
+ mono_gc_wbarrier_generic_store (control_chars, (MonoObject*) mono_array_new (mono_domain_get (), mono_defaults.byte_class, 17));
if (tcgetattr (STDIN_FILENO, &initial_attr) == -1)
return FALSE;
mono_attr.c_iflag &= ~(IXON|IXOFF);
mono_attr.c_cc [VMIN] = 1;
mono_attr.c_cc [VTIME] = 0;
+#ifdef VDSUSP
+ /* Disable C-y being used as a suspend character on OSX */
+ mono_attr.c_cc [VDSUSP] = 255;
+#endif
if (tcsetattr (STDIN_FILENO, TCSANOW, &mono_attr) == -1)
return FALSE;
return TRUE;
}
+#endif /* #if defined(__native_client__) */
+