/* Top level stuff for GDB, the GNU debugger.
- Copyright (C) 1999-2002, 2004-2005, 2007-2012 Free Software
- Foundation, Inc.
+ Copyright (C) 1999-2014 Free Software Foundation, Inc.
Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
#include "defs.h"
#include "top.h"
#include "inferior.h"
+#include "infrun.h"
#include "target.h"
#include "terminal.h" /* for job_control */
#include "event-loop.h"
#include "observer.h"
#include "continuations.h"
#include "gdbcmd.h" /* for dont_repeat() */
+#include "annotate.h"
+#include "maint.h"
/* readline include files. */
#include "readline/readline.h"
static void handle_sighup (int sig);
#endif
static void handle_sigfpe (int sig);
-#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-static void handle_sigwinch (int sig);
-#endif
/* Functions to be invoked by the event loop in response to
signals. */
#ifdef STOP_SIGNAL
static void async_stop_sig (gdb_client_data);
#endif
+static void async_sigterm_handler (gdb_client_data arg);
/* Readline offers an alternate interface, via callback
functions. These are all included in the file callback.c in the
handlers mark these functions as ready to be executed and the event
loop, in a later iteration, calls them. See the function
invoke_async_signal_handler. */
-void *sigint_token;
+static struct async_signal_handler *sigint_token;
#ifdef SIGHUP
-void *sighup_token;
+static struct async_signal_handler *sighup_token;
#endif
#ifdef SIGQUIT
-void *sigquit_token;
-#endif
-void *sigfpe_token;
-#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-void *sigwinch_token;
+static struct async_signal_handler *sigquit_token;
#endif
+static struct async_signal_handler *sigfpe_token;
#ifdef STOP_SIGNAL
-void *sigtstp_token;
+static struct async_signal_handler *sigtstp_token;
#endif
+static struct async_signal_handler *async_sigterm_token;
/* Structure to save a partially entered command. This is used when
the user types '\' at the end of a command line. This is necessary
}
/* Initialize all the necessary variables, start the event loop,
- register readline, and stdin, start the loop. */
+ register readline, and stdin, start the loop. The DATA is the
+ interpreter data cookie, ignored for now. */
+
void
-cli_command_loop (void)
+cli_command_loop (void *data)
{
display_gdb_prompt (0);
char *actual_gdb_prompt = NULL;
struct cleanup *old_chain;
+ annotate_display_prompt ();
+
/* Reset the nesting depth used when trace-commands is set. */
reset_command_nest_depth ();
- /* Each interpreter has its own rules on displaying the command
- prompt. */
- if (!current_interp_display_prompt_p ())
- return;
-
old_chain = make_cleanup (free_current_contents, &actual_gdb_prompt);
/* Do not call the python hook on an explicit prompt change as
rl_callback_handler_remove(), does the job. */
rl_callback_handler_remove ();
+ do_cleanups (old_chain);
return;
}
else
int stdin_is_tty = ISATTY (stdin);
struct cleanup *stat_chain;
- quit_flag = 0;
+ clear_quit_flag ();
if (instream == stdin && stdin_is_tty)
reinitialize_more_filter ();
char *p;
char *p1;
char *nline;
- char got_eof = 0;
-
int repeat = (instream == stdin);
if (annotation_level > 1 && instream == stdin)
and exit from gdb. */
if (!rl || rl == (char *) EOF)
{
- got_eof = 1;
command_handler (0);
return; /* Lint. */
}
*p = 0;
/* Add line to history if appropriate. */
- if (instream == stdin
- && ISATTY (stdin) && *linebuffer)
+ if (*linebuffer && input_from_terminal_p ())
add_history (linebuffer);
/* Note: lines consisting solely of comments are added to the command
sigint_token =
create_async_signal_handler (async_request_quit, NULL);
signal (SIGTERM, handle_sigterm);
+ async_sigterm_token
+ = create_async_signal_handler (async_sigterm_handler, NULL);
/* If SIGTRAP was set to SIG_IGN, then the SIG_IGN will get passed
to the inferior and breakpoints will be ignored. */
sigfpe_token =
create_async_signal_handler (async_float_handler, NULL);
-#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
- signal (SIGWINCH, handle_sigwinch);
- sigwinch_token =
- create_async_signal_handler (SIGWINCH_HANDLER, NULL);
-#endif
#ifdef STOP_SIGNAL
sigtstp_token =
create_async_signal_handler (async_stop_sig, NULL);
#endif
-
-}
-
-void
-mark_async_signal_handler_wrapper (void *token)
-{
- mark_async_signal_handler ((struct async_signal_handler *) token);
}
/* Tell the event loop what to do if SIGINT is received.
set quit_flag to 1 here. Then if QUIT is called before we get to
the event loop, we will unwind as expected. */
- quit_flag = 1;
+ set_quit_flag ();
/* If immediate_quit is set, we go ahead and process the SIGINT right
away, even if we usually would defer this to the event loop. The
gdb_call_async_signal_handler (sigint_token, immediate_quit);
}
+/* Handle GDB exit upon receiving SIGTERM if target_can_async_p (). */
+
+static void
+async_sigterm_handler (gdb_client_data arg)
+{
+ quit_force (NULL, stdin == instream);
+}
+
+/* See defs.h. */
+volatile int sync_quit_force_run;
+
/* Quit GDB if SIGTERM is received.
GDB would quit anyway, but this way it will clean up properly. */
void
handle_sigterm (int sig)
{
signal (sig, handle_sigterm);
- quit_force ((char *) 0, stdin == instream);
+
+ /* Call quit_force in a signal safe way.
+ quit_force itself is not signal safe. */
+ if (target_can_async_p ())
+ mark_async_signal_handler (async_sigterm_token);
+ else
+ {
+ sync_quit_force_run = 1;
+ set_quit_flag ();
+ }
}
/* Do the quit. All the checks have been done by the caller. */
/* If the quit_flag has gotten reset back to 0 by the time we get
back here, that means that an exception was thrown to unwind the
current command before we got back to the event loop. So there
- is no reason to call quit again here, unless immediate_quit is
- set. */
+ is no reason to call quit again here. */
- if (quit_flag || immediate_quit)
+ if (check_quit_flag ())
quit ();
}
static void
handle_sigquit (int sig)
{
- mark_async_signal_handler_wrapper (sigquit_token);
+ mark_async_signal_handler (sigquit_token);
signal (sig, handle_sigquit);
}
#endif
static void
handle_sighup (int sig)
{
- mark_async_signal_handler_wrapper (sighup_token);
+ mark_async_signal_handler (sighup_token);
signal (sig, handle_sighup);
}
TRY_CATCH (exception, RETURN_MASK_ALL)
{
- pop_all_targets (1);
+ pop_all_targets ();
}
signal (SIGHUP, SIG_DFL); /*FIXME: ??????????? */
void
handle_stop_sig (int sig)
{
- mark_async_signal_handler_wrapper (sigtstp_token);
+ mark_async_signal_handler (sigtstp_token);
signal (sig, handle_stop_sig);
}
static void
handle_sigfpe (int sig)
{
- mark_async_signal_handler_wrapper (sigfpe_token);
+ mark_async_signal_handler (sigfpe_token);
signal (sig, handle_sigfpe);
}
divide by zero causes this, so "float" is a misnomer. */
error (_("Erroneous arithmetic operation."));
}
-
-/* Tell the event loop what to do if SIGWINCH is received.
- See event-signal.c. */
-#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-static void
-handle_sigwinch (int sig)
-{
- mark_async_signal_handler_wrapper (sigwinch_token);
- signal (sig, handle_sigwinch);
-}
-#endif
\f
/* Called by do_setshow_command. */
time. */
if (!batch_silent)
gdb_stdout = stdio_fileopen (stdout);
- gdb_stderr = stdio_fileopen (stderr);
+ gdb_stderr = stderr_fileopen ();
gdb_stdlog = gdb_stderr; /* for moment */
gdb_stdtarg = gdb_stderr; /* for moment */
gdb_stdtargerr = gdb_stderr; /* for moment */