#include "defs.h"
#include "top.h"
#include "inferior.h"
+#include "target.h"
#include "terminal.h" /* for job_control */
#include "signals.h"
#include "event-loop.h"
#include <readline/readline.h>
#include <readline/history.h>
+#include <signal.h>
+
/* readline defines this. */
#undef savestring
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. */
-PTR sigint_token;
+void *sigint_token;
#ifdef SIGHUP
-PTR sighup_token;
+void *sighup_token;
#endif
-PTR sigquit_token;
-PTR sigfpe_token;
+void *sigquit_token;
+void *sigfpe_token;
#if defined(SIGWINCH) && defined(SIGWINCH_HANDLER)
-PTR sigwinch_token;
+void *sigwinch_token;
#endif
#ifdef STOP_SIGNAL
-PTR sigtstp_token;
+void *sigtstp_token;
#endif
/* Structure to save a partially entered command. This is used when
readline_input_state;
\f
-/* Wrapper function foe calling into the readline library. The event
+/* Wrapper function for calling into the readline library. The event
loop expects the callback function to have a paramter, while readline
expects none. */
static void
int prompt_length = 0;
char *gdb_prompt = get_prompt ();
+#ifdef UI_OUT
+ /* When an alternative interpreter has been installed, do not
+ display the comand prompt. */
+ if (interpreter_p)
+ return;
+#endif
- if (target_executing && sync_execution)
+ if (target_executing && sync_execution)
{
/* This is to trick readline into not trying to display the
- prompt. Even though we display the prompt using this
- function, readline still tries to do its own display if we
- don't call rl_callback_handler_install and
- rl_callback_handler_remove (which readline detects because a
- global variable is not set). If readline did that, it could
- mess up gdb signal handlers for SIGINT. Readline assumes
- that between calls to rl_set_signals and rl_clear_signals gdb
- doesn't do anything with the signal handlers. Well, that's
- not the case, because when the target executes we change the
- SIGINT signal handler. If we allowed readline to display the
- prompt, the signal handler change would happen exactly
- between the calls to the above two functions.
- Calling rl_callback_handler_remove(), does the job. */
+ prompt. Even though we display the prompt using this
+ function, readline still tries to do its own display if we
+ don't call rl_callback_handler_install and
+ rl_callback_handler_remove (which readline detects because a
+ global variable is not set). If readline did that, it could
+ mess up gdb signal handlers for SIGINT. Readline assumes
+ that between calls to rl_set_signals and rl_clear_signals gdb
+ doesn't do anything with the signal handlers. Well, that's
+ not the case, because when the target executes we change the
+ SIGINT signal handler. If we allowed readline to display the
+ prompt, the signal handler change would happen exactly
+ between the calls to the above two functions.
+ Calling rl_callback_handler_remove(), does the job. */
rl_callback_handler_remove ();
return;
in effect, until the user does another 'set prompt'. */
if (strcmp (PROMPT (0), PROMPT (-1)))
{
- free (PROMPT (-1));
+ xfree (PROMPT (-1));
PROMPT (-1) = savestring (PROMPT (0), strlen (PROMPT (0)));
}
- free (PREFIX (0));
- free (PROMPT (0));
- free (SUFFIX (0));
+ xfree (PREFIX (0));
+ xfree (PROMPT (0));
+ xfree (SUFFIX (0));
the_prompts.top--;
}
instead of calling gdb_readline2, give gdb a chance to detect
errors and do something. */
void
-stdin_event_handler (int error, int fd, gdb_client_data client_data)
+stdin_event_handler (int error, gdb_client_data client_data)
{
if (error)
{
- printf_unfiltered ("error detected on stdin, fd %d\n", fd);
- delete_file_handler (fd);
+ printf_unfiltered ("error detected on stdin\n");
+ delete_file_handler (input_fd);
discard_all_continuations ();
/* If stdin died, we may as well kill gdb. */
- exit (1);
+ quit_command ((char *) 0, stdin == instream);
}
else
- (*call_readline) (client_data);
+ (*call_readline) (client_data);
}
+/* Re-enable stdin after the end of an execution command in
+ synchronous mode, or after an error from the target, and we aborted
+ the exec operation. */
+
+void
+async_enable_stdin (void *dummy)
+{
+ /* See NOTE in async_disable_stdin() */
+ /* FIXME: cagney/1999-09-27: Call this before clearing
+ sync_execution. Current target_terminal_ours() implementations
+ check for sync_execution before switching the terminal. */
+ target_terminal_ours ();
+ pop_prompt ();
+ sync_execution = 0;
+}
+
+/* Disable reads from stdin (the console) marking the command as
+ synchronous. */
+
+void
+async_disable_stdin (void)
+{
+ sync_execution = 1;
+ push_prompt ("", "", "");
+ /* FIXME: cagney/1999-09-27: At present this call is technically
+ redundant since infcmd.c and infrun.c both already call
+ target_terminal_inferior(). As the terminal handling (in
+ sync/async mode) is refined, the duplicate calls can be
+ eliminated (Here or in infcmd.c/infrun.c). */
+ target_terminal_inferior ();
+ /* Add the reinstate of stdin to the list of cleanups to be done
+ in case the target errors out and dies. These cleanups are also
+ done in case of normal successful termination of the execution
+ command, by complete_execution(). */
+ make_exec_error_cleanup (async_enable_stdin, NULL);
+}
\f
+
/* Handles a gdb command. This function is called by
command_line_handler, which has processed one or more input lines
into COMMAND. */
quit_flag = 0;
if (instream == stdin && stdin_is_tty)
reinitialize_more_filter ();
- old_chain = make_cleanup ((make_cleanup_func) command_loop_marker, 0);
+ old_chain = make_cleanup (null_cleanup, 0);
#if defined(TUI)
insert_mode = 0;
execute_command (command, instream == stdin);
/* Set things up for this function to be compete later, once the
- executin has completed, if we are doing an execution command,
+ execution has completed, if we are doing an execution command,
otherwise, just go ahead and finish. */
- if (target_has_async && target_executing)
+ if (target_can_async_p () && target_executing)
{
arg1 =
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
arg1->next = arg2;
arg2->next = NULL;
- arg1->data = (PTR) time_at_cmd_start;
- arg2->data = (PTR) space_at_cmd_start;
+ arg1->data.integer = time_at_cmd_start;
+ arg2->data.integer = space_at_cmd_start;
add_continuation (command_line_handler_continuation, arg1);
}
/* Do any commands attached to breakpoint we stopped at. Only if we
are always running synchronously. Or if we have just executed a
command that doesn't start the target. */
- if (!target_has_async || !target_executing)
+ if (!target_can_async_p () || !target_executing)
{
bpstat_do_actions (&stop_bpstat);
do_cleanups (old_chain);
extern int display_time;
extern int display_space;
- long time_at_cmd_start = (long) arg->data;
- long space_at_cmd_start = (long) arg->next->data;
+ long time_at_cmd_start = arg->data.longint;
+ long space_at_cmd_start = arg->next->data.longint;
bpstat_do_actions (&stop_bpstat);
/*do_cleanups (old_chain); *//*?????FIXME????? */
{
strcpy (linebuffer, readline_input_state.linebuffer);
p = readline_input_state.linebuffer_ptr;
- free (readline_input_state.linebuffer);
+ xfree (readline_input_state.linebuffer);
more_to_come = 0;
pop_prompt ();
}
while (*p1)
*p++ = *p1++;
- free (rl); /* Allocated in readline. */
+ xfree (rl); /* Allocated in readline. */
if (*(p - 1) == '\\')
{
/* If there was an error, call this function again. */
if (expanded < 0)
{
- free (history_value);
+ xfree (history_value);
return;
}
if (strlen (history_value) > linelength)
}
strcpy (linebuffer, history_value);
p = linebuffer + strlen (linebuffer);
- free (history_value);
+ xfree (history_value);
}
}
if we are called again fgetc will still return EOF and
we'll return NULL then. */
break;
- free (result);
+ xfree (result);
(*input_handler) (0);
}
}
void
-mark_async_signal_handler_wrapper (PTR token)
+mark_async_signal_handler_wrapper (void *token)
{
mark_async_signal_handler ((struct async_signal_handler *) token);
}
/* Tell the event loop what to do if SIGHUP is received.
See event-signal.c. */
static void
-handle_sighup (sig)
- int sig;
+handle_sighup (int sig)
{
mark_async_signal_handler_wrapper (sighup_token);
signal (sig, handle_sighup);
char *prompt = get_prompt ();
#if STOP_SIGNAL == SIGTSTP
signal (SIGTSTP, SIG_DFL);
+#if HAVE_SIGPROCMASK
+ {
+ sigset_t zero;
+ sigemptyset (&zero);
+ sigprocmask (SIG_SETMASK, &zero, 0);
+ }
+#else
sigsetmask (0);
+#endif
kill (getpid (), SIGTSTP);
signal (SIGTSTP, handle_stop_sig);
#else
void
_initialize_event_loop (void)
{
- if (async_p)
+ if (event_loop_p)
{
- /* When a character is detected on instream by select or poll,
- readline will be invoked via this callback function. */
- call_readline = rl_callback_read_char_wrapper;
+ /* If the input stream is connected to a terminal, turn on
+ editing. */
+ if (ISATTY (instream))
+ {
+ /* Tell gdb that we will be using the readline library. This
+ could be overwritten by a command in .gdbinit like 'set
+ editing on' or 'off'. */
+ async_command_editing_p = 1;
+
+ /* When a character is detected on instream by select or
+ poll, readline will be invoked via this callback
+ function. */
+ call_readline = rl_callback_read_char_wrapper;
+ }
+ else
+ {
+ async_command_editing_p = 0;
+ call_readline = gdb_readline2;
+ }
/* When readline has read an end-of-line character, it passes
the complete line to gdb for processing. command_line_handler
only when it actually exists (I.e. after we say 'run' or
after we connect to a remote target. */
add_file_handler (input_fd, stdin_event_handler, 0);
-
- /* Tell gdb that we will be using the readline library. This
- could be overwritten by a command in .gdbinit like 'set
- editing on' or 'off'. */
- async_command_editing_p = 1;
}
}