/* Top level stuff for GDB, the GNU debugger.
- Copyright (C) 1999-2013 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 "event-top.h"
#include "interps.h"
#include <signal.h>
-#include "exceptions.h"
#include "cli/cli-script.h" /* for reset_command_nest_depth */
#include "main.h"
#include "gdbthread.h"
#include "continuations.h"
#include "gdbcmd.h" /* for dont_repeat() */
#include "annotate.h"
+#include "maint.h"
/* readline include files. */
#include "readline/readline.h"
#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
#ifdef STOP_SIGNAL
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);
/* 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
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. */
sigtstp_token =
create_async_signal_handler (async_stop_sig, NULL);
#endif
-
}
/* Tell the event loop what to do if SIGINT is received.
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. */
TRY_CATCH (exception, RETURN_MASK_ALL)
{
- pop_all_targets (1);
+ pop_all_targets ();
}
signal (SIGHUP, SIG_DFL); /*FIXME: ??????????? */
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 */