static void go_command (char *line_no, int from_tty);
-static int strip_bg_char (char **);
-
void _initialize_infcmd (void);
#define ERROR_NO_INFERIOR \
}
\f
-/* This function detects whether or not a '&' character (indicating
- background execution) has been added as *the last* of the arguments ARGS
- of a command. If it has, it removes it and returns 1. Otherwise it
- does nothing and returns 0. */
+/* This function strips the '&' character (indicating background
+ execution) that is added as *the last* of the arguments ARGS of a
+ command. A copy of the incoming ARGS without the '&' is returned,
+ unless the resulting string after stripping is empty, in which case
+ NULL is returned. *BG_CHAR_P is an output boolean that indicates
+ whether the '&' character was found. */
-static int
-strip_bg_char (char **args)
+static char *
+strip_bg_char (const char *args, int *bg_char_p)
{
- char *p = NULL;
+ const char *p;
- p = strchr (*args, '&');
+ if (args == NULL || *args == '\0')
+ {
+ *bg_char_p = 0;
+ return NULL;
+ }
- if (p)
+ p = args + strlen (args);
+ if (p[-1] == '&')
{
- if (p == (*args + strlen (*args) - 1))
- {
- if (strlen (*args) > 1)
- {
- do
- p--;
- while (*p == ' ' || *p == '\t');
- *(p + 1) = '\0';
- }
- else
- *args = 0;
- return 1;
- }
+ p--;
+ while (p > args && isspace (p[-1]))
+ p--;
+
+ *bg_char_p = 1;
+ if (p != args)
+ return savestring (args, p - args);
+ else
+ return NULL;
}
- return 0;
+
+ *bg_char_p = 0;
+ return xstrdup (args);
}
/* Common actions to take after creating any sort of inferior, by any
ptid_t ptid;
struct ui_out *uiout = current_uiout;
struct target_ops *run_target;
- int async_exec = 0;
+ int async_exec;
+ struct cleanup *args_chain;
dont_repeat ();
reopen_exec_file ();
reread_symbols ();
- if (args != NULL)
- async_exec = strip_bg_char (&args);
+ args = strip_bg_char (args, &async_exec);
+ args_chain = make_cleanup (xfree, args);
/* Do validation and preparation before possibly changing anything
in the inferior. */
ui_out_flush (uiout);
}
+ /* Done with ARGS. */
+ do_cleanups (args_chain);
+
/* We call get_inferior_args() because we might need to compute
the value now. */
run_target->to_create_inferior (run_target, exec_file, get_inferior_args (),
iterate_over_threads (proceed_thread_callback, NULL);
+ if (sync_execution)
+ {
+ /* If all threads in the target were already running,
+ proceed_thread_callback ends up never calling proceed,
+ and so nothing calls this to put the inferior's terminal
+ settings in effect and remove stdin from the event loop,
+ which we must when running a foreground command. E.g.:
+
+ (gdb) c -a&
+ Continuing.
+ <all threads are running now>
+ (gdb) c -a
+ Continuing.
+ <no thread was resumed, but the inferior now owns the terminal>
+ */
+ target_terminal_inferior ();
+ }
+
/* Restore selected ptid. */
do_cleanups (old_chain);
}
static void
continue_command (char *args, int from_tty)
{
- int async_exec = 0;
+ int async_exec;
int all_threads = 0;
+ struct cleanup *args_chain;
+
ERROR_NO_INFERIOR;
/* Find out whether we must run in the background. */
- if (args != NULL)
- async_exec = strip_bg_char (&args);
+ args = strip_bg_char (args, &async_exec);
+ args_chain = make_cleanup (xfree, args);
prepare_execution_command (¤t_target, async_exec);
}
}
+ /* Done with ARGS. */
+ do_cleanups (args_chain);
+
if (from_tty)
printf_filtered (_("Continuing.\n"));
{
int count = 1;
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
- int async_exec = 0;
+ int async_exec;
int thread = -1;
+ struct cleanup *args_chain;
ERROR_NO_INFERIOR;
ensure_not_tfind_mode ();
ensure_valid_thread ();
ensure_not_running ();
- if (count_string)
- async_exec = strip_bg_char (&count_string);
+ count_string = strip_bg_char (count_string, &async_exec);
+ args_chain = make_cleanup (xfree, count_string);
prepare_execution_command (¤t_target, async_exec);
count = count_string ? parse_and_eval_long (count_string) : 1;
+ /* Done with ARGS. */
+ do_cleanups (args_chain);
+
if (!single_inst || skip_subroutines) /* Leave si command alone. */
{
struct thread_info *tp = inferior_thread ();
struct symtab_and_line sal;
struct symbol *fn;
struct symbol *sfn;
- int async_exec = 0;
+ int async_exec;
+ struct cleanup *args_chain;
ERROR_NO_INFERIOR;
ensure_not_tfind_mode ();
ensure_not_running ();
/* Find out whether we must run in the background. */
- if (arg != NULL)
- async_exec = strip_bg_char (&arg);
+ arg = strip_bg_char (arg, &async_exec);
+ args_chain = make_cleanup (xfree, arg);
prepare_execution_command (¤t_target, async_exec);
sal = sals.sals[0];
xfree (sals.sals);
+ /* Done with ARGS. */
+ do_cleanups (args_chain);
+
if (sal.symtab == 0 && sal.pc == 0)
error (_("No source file has been specified."));
signal_command (char *signum_exp, int from_tty)
{
enum gdb_signal oursig;
- int async_exec = 0;
+ int async_exec;
+ struct cleanup *args_chain;
dont_repeat (); /* Too dangerous. */
ERROR_NO_INFERIOR;
ensure_not_running ();
/* Find out whether we must run in the background. */
- if (signum_exp != NULL)
- async_exec = strip_bg_char (&signum_exp);
+ signum_exp = strip_bg_char (signum_exp, &async_exec);
+ args_chain = make_cleanup (xfree, signum_exp);
prepare_execution_command (¤t_target, async_exec);
static void
until_command (char *arg, int from_tty)
{
- int async_exec = 0;
+ int async_exec;
+ struct cleanup *args_chain;
ERROR_NO_INFERIOR;
ensure_not_tfind_mode ();
ensure_not_running ();
/* Find out whether we must run in the background. */
- if (arg != NULL)
- async_exec = strip_bg_char (&arg);
+ arg = strip_bg_char (arg, &async_exec);
+ args_chain = make_cleanup (xfree, arg);
prepare_execution_command (¤t_target, async_exec);
until_break_command (arg, from_tty, 0);
else
until_next_command (from_tty);
+
+ /* Done with ARGS. */
+ do_cleanups (args_chain);
}
static void
advance_command (char *arg, int from_tty)
{
- int async_exec = 0;
+ int async_exec;
+ struct cleanup *args_chain;
ERROR_NO_INFERIOR;
ensure_not_tfind_mode ();
error_no_arg (_("a location"));
/* Find out whether we must run in the background. */
- if (arg != NULL)
- async_exec = strip_bg_char (&arg);
+ arg = strip_bg_char (arg, &async_exec);
+ args_chain = make_cleanup (xfree, arg);
prepare_execution_command (¤t_target, async_exec);
until_break_command (arg, from_tty, 1);
+
+ /* Done with ARGS. */
+ do_cleanups (args_chain);
}
\f
/* Return the value of the result of a function at the end of a 'finish'
{
struct frame_info *frame;
struct symbol *function;
-
- int async_exec = 0;
+ int async_exec;
+ struct cleanup *args_chain;
ERROR_NO_INFERIOR;
ensure_not_tfind_mode ();
ensure_not_running ();
/* Find out whether we must run in the background. */
- if (arg != NULL)
- async_exec = strip_bg_char (&arg);
+ arg = strip_bg_char (arg, &async_exec);
+ args_chain = make_cleanup (xfree, arg);
prepare_execution_command (¤t_target, async_exec);
if (arg)
error (_("The \"finish\" command does not take any arguments."));
+ /* Done with ARGS. */
+ do_cleanups (args_chain);
+
frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
if (frame == 0)
error (_("\"finish\" not meaningful in the outermost frame."));
void
attach_command (char *args, int from_tty)
{
- int async_exec = 0;
+ int async_exec;
+ struct cleanup *args_chain;
struct target_ops *attach_target;
dont_repeat (); /* Not for the faint of heart */
this function should probably be moved into target_pre_inferior. */
target_pre_inferior (from_tty);
- if (args != NULL)
- async_exec = strip_bg_char (&args);
+ args = strip_bg_char (args, &async_exec);
+ args_chain = make_cleanup (xfree, args);
attach_target = find_attach_target ();
shouldn't refer to attach_target again. */
attach_target = NULL;
+ /* Done with ARGS. */
+ do_cleanups (args_chain);
+
/* Set up the "saved terminal modes" of the inferior
based on what modes we are starting it with. */
target_terminal_init ();