+2008-04-24 Vladimir Prus <vladimir@codesourcery.com>
+
+ exec_cleanup murder.
+ * breakpoint.c (until_break_command_continuation): Add
+ the 'error' parameter. Directly delete the breakoint as
+ opposed to running cleanups.
+ (until_break_command): Install continuation only
+ after starting the target. Don't use exec cleanups,
+ use ordinary cleanups. Discard cleanups is successfully
+ started the target in async mode.
+ (make_cleanup_delete_breakpoint): Remove.
+ * breakpoint.h (make_cleanup_delete_breakpoint): Remove
+ declaration.
+ * defs.h (do_exec_cleanups, make_exec_cleanup): Remove
+ declarations.
+ (struct continations): Add the 'error' parameter to the
+ continuation_hook field.
+ (add_continuation, do_all_continuations)
+ (add_intermediate_continuation)
+ (do_all_intermediate_continuations): Add the 'error' parameter.
+ * exceptions.c (throw_exception): Don't call do_exec_cleanups.
+ * inf-loop.c (inferior_event_handler): Instead of calling
+ discard_all_continuations, use do_all_continuations with 1 as
+ 'error' parameter. Pass 0 as 'error' parameter in existing uses
+ of discard_all_continuations.
+ * infcmd.c (step_1): Do not use exec cleanup. For async case, discard
+ cleanups.
+ (step_once): Install continuation only after resuming the target.
+ (step_1_continuation): Disable longjmp breakpoint on error.
+ (finish_command_continuation): Add the error parameter. Delete
+ the finish breakpoint directly, do not use cleanups.
+ (finish_command): Do not use exec_cleanups. Always setup
+ continuation. For sync case, immediately run them.
+ (attach_command_continuation): Add the error parameter.
+ * infrun.c (fetch_inferior_event): Do not use exec cleanups to
+ remove step_resume_breakpoint -- adjust delete it directly.
+ * interps.c (interp_set): Adjust call to do_all_continations.
+ * mi/mi-interp.c (mi_interpreter_exec_continuation): Do not
+ do exec cleanups.
+ * mi/mi-main.c (mi_cmd_target_select): Do not do exec
+ cleanups.
+ (mi_cmd_execute): Do not use exec_cleanup.
+ (mi_execute_async_cli_command): Simplify the string concatenation
+ logic. Do no use exec cleanup.
+ (mi_exec_async_cli_cmd_continuation): New parameter error.
+ Free last_async_command.
+ * top.c (command_line_handler_continuation): New parameter error.
+ * utils.c (exec_cleanup_chain, make_exec_cleanup)
+ (do_exec_cleanups): Remove.
+ (add_continuation, do_all_continations)
+ (add_intermediate_continuation)
+ (do_all_intermediate_continuations): New parameter error.
+
2008-04-24 Vladimir Prus <vladimir@codesourcery.com>
* breakpoint.h (bp_location_p): New typedef.
/* Prototypes for local functions. */
-static void until_break_command_continuation (struct continuation_arg *arg);
+static void until_break_command_continuation (struct continuation_arg *arg,
+ int error);
static void catch_command_1 (char *, int, int);
care of cleaning up the temporary breakpoints set up by the until
command. */
static void
-until_break_command_continuation (struct continuation_arg *arg)
+until_break_command_continuation (struct continuation_arg *arg, int error)
{
- struct cleanup *cleanups;
-
- cleanups = (struct cleanup *) arg->data.pointer;
- do_exec_cleanups (cleanups);
+ delete_breakpoint ((struct breakpoint *)(arg->data.pointer));
+ if (arg->next)
+ delete_breakpoint ((struct breakpoint *)(arg->next->data.pointer));
}
void
struct frame_info *frame = get_selected_frame (NULL);
struct frame_info *prev_frame = get_prev_frame (frame);
struct breakpoint *breakpoint;
+ struct breakpoint *breakpoint2 = NULL;
struct cleanup *old_chain;
struct continuation_arg *arg1;
+ struct continuation_arg *arg2;
clear_proceed_status ();
breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame),
bp_until);
- if (!target_can_async_p ())
- old_chain = make_cleanup_delete_breakpoint (breakpoint);
- else
- old_chain = make_exec_cleanup_delete_breakpoint (breakpoint);
-
- /* If we are running asynchronously, and the target supports async
- execution, we are not waiting for the target to stop, in the call
- tp proceed, below. This means that we cannot delete the
- brekpoints until the target has actually stopped. The only place
- where we get a chance to do that is in fetch_inferior_event, so
- we must set things up for that. */
-
- if (target_can_async_p ())
- {
- /* In this case the arg for the continuation is just the point
- in the exec_cleanups chain from where to start doing
- cleanups, because all the continuation does is the cleanups in
- the exec_cleanup_chain. */
- arg1 =
- (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
- arg1->next = NULL;
- arg1->data.pointer = old_chain;
-
- add_continuation (until_break_command_continuation, arg1);
- }
+ old_chain = make_cleanup_delete_breakpoint (breakpoint);
/* Keep within the current frame, or in frames called by the current
one. */
{
sal = find_pc_line (get_frame_pc (prev_frame), 0);
sal.pc = get_frame_pc (prev_frame);
- breakpoint = set_momentary_breakpoint (sal, get_frame_id (prev_frame),
- bp_until);
- if (!target_can_async_p ())
- make_cleanup_delete_breakpoint (breakpoint);
- else
- make_exec_cleanup_delete_breakpoint (breakpoint);
+ breakpoint2 = set_momentary_breakpoint (sal, get_frame_id (prev_frame),
+ bp_until);
+ make_cleanup_delete_breakpoint (breakpoint2);
}
proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
- /* Do the cleanups now, anly if we are not running asynchronously,
- of if we are, but the target is still synchronous. */
- if (!target_can_async_p ())
+
+ /* If we are running asynchronously, and proceed call above has actually
+ managed to start the target, arrange for breakpoints to be
+ deleted when the target stops. Otherwise, we're already stopped and
+ delete breakpoints via cleanup chain. */
+
+ if (target_can_async_p () && target_executing)
+ {
+ arg1 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg1->next = NULL;
+ arg1->data.pointer = breakpoint;
+
+ if (breakpoint2)
+ {
+ arg2 = (struct continuation_arg *)
+ xmalloc ( sizeof (struct continuation_arg));
+ arg2->next = NULL;
+ arg2->data.pointer = breakpoint2;
+ arg1->next = arg2;
+ }
+
+ discard_cleanups (old_chain);
+ add_continuation (until_break_command_continuation, arg1);
+ }
+ else
do_cleanups (old_chain);
}
return make_cleanup (do_delete_breakpoint_cleanup, b);
}
-struct cleanup *
-make_exec_cleanup_delete_breakpoint (struct breakpoint *b)
-{
- return make_exec_cleanup (do_delete_breakpoint_cleanup, b);
-}
-
void
delete_command (char *arg, int from_tty)
{
extern struct cleanup *make_cleanup_delete_breakpoint (struct breakpoint *);
-extern struct cleanup *make_exec_cleanup_delete_breakpoint (struct breakpoint *);
-
extern void delete_breakpoint (struct breakpoint *);
extern void breakpoint_auto_delete (bpstat);
extern void do_cleanups (struct cleanup *);
extern void do_final_cleanups (struct cleanup *);
-extern void do_exec_cleanups (struct cleanup *);
extern void discard_cleanups (struct cleanup *);
extern void discard_final_cleanups (struct cleanup *);
extern struct cleanup *make_my_cleanup (struct cleanup **,
make_cleanup_ftype *, void *);
-extern struct cleanup *make_exec_cleanup (make_cleanup_ftype *, void *);
-
extern struct cleanup *save_cleanups (void);
extern struct cleanup *save_final_cleanups (void);
extern struct cleanup *save_my_cleanups (struct cleanup **);
struct continuation
{
- void (*continuation_hook) (struct continuation_arg *);
+ void (*continuation_hook) (struct continuation_arg *, int);
struct continuation_arg *arg_list;
struct continuation *next;
};
extern struct continuation *intermediate_continuation;
/* From utils.c */
-extern void add_continuation (void (*)(struct continuation_arg *),
+extern void add_continuation (void (*)(struct continuation_arg *, int),
struct continuation_arg *);
-extern void do_all_continuations (void);
+extern void do_all_continuations (int error);
extern void discard_all_continuations (void);
-extern void add_intermediate_continuation (void (*)(struct continuation_arg *),
+extern void add_intermediate_continuation (void (*)(struct continuation_arg *, int),
struct continuation_arg *);
-extern void do_all_intermediate_continuations (void);
+extern void do_all_intermediate_continuations (int error);
extern void discard_all_intermediate_continuations (void);
/* String containing the current directory (what getwd would return). */
disable_current_display ();
do_cleanups (ALL_CLEANUPS);
- /* When we implement non-stop mode, this should be redone. If we get
- exception in a command pertaining to one thread, or maybe even not
- involving inferior at all, we should not do exec cleanups for all
- threads. */
- if (target_can_async_p () && !target_executing)
- do_exec_cleanups (ALL_CLEANUPS);
/* Jump to the containing catch_errors() call, communicating REASON
to that call via setjmp's return value. Note that REASON can't
printf_unfiltered (_("error detected from target.\n"));
target_async (NULL, 0);
pop_target ();
- discard_all_continuations ();
+ do_all_continuations (1);
async_enable_stdin ();
break;
{
target_async (NULL, 0);
pop_target ();
- discard_all_continuations ();
+ do_all_continuations (1);
async_enable_stdin ();
display_gdb_prompt (0);
}
got interrupted by a breakpoint, still do the pending
continuations. The continuation itself is responsible for
distinguishing the cases. */
- do_all_intermediate_continuations ();
+ do_all_intermediate_continuations (0);
- do_all_continuations ();
+ do_all_continuations (0);
if (current_language != expected_language)
{
case INF_EXEC_CONTINUE:
/* Is there anything left to do for the command issued to
complete? */
- do_all_intermediate_continuations ();
+ do_all_intermediate_continuations (0);
break;
case INF_QUIT_REQ:
static void print_return_value (struct type *func_type,
struct type *value_type);
-static void finish_command_continuation (struct continuation_arg *);
+static void finish_command_continuation (struct continuation_arg *,
+ int error_p);
static void until_next_command (int);
static void step_1 (int, int, char *);
static void step_once (int skip_subroutines, int single_inst, int count);
-static void step_1_continuation (struct continuation_arg *arg);
+static void step_1_continuation (struct continuation_arg *arg, int error_p);
static void next_command (char *, int);
{
int count = 1;
struct frame_info *frame;
- struct cleanup *cleanups = 0;
+ struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
int async_exec = 0;
ERROR_NO_INFERIOR;
if (!single_inst || skip_subroutines) /* leave si command alone */
{
enable_longjmp_breakpoint ();
- if (!target_can_async_p ())
- cleanups = make_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/);
- else
- make_exec_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/);
+ make_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/);
}
/* In synchronous case, all is well, just use the regular for loop. */
break;
}
- if (!single_inst || skip_subroutines)
- do_cleanups (cleanups);
+ do_cleanups (cleanups);
return;
}
/* In case of asynchronous target things get complicated, do only
and handle them one at the time, through step_once(). */
else
{
- if (target_can_async_p ())
- step_once (skip_subroutines, single_inst, count);
+ step_once (skip_subroutines, single_inst, count);
+ /* We are running, and the contination is installed. It will
+ disable the longjmp breakpoint as appropriate. */
+ discard_cleanups (cleanups);
}
}
proceed(), via step_once(). Basically it is like step_once and
step_1_continuation are co-recursive. */
static void
-step_1_continuation (struct continuation_arg *arg)
+step_1_continuation (struct continuation_arg *arg, int error_p)
{
- int count;
- int skip_subroutines;
- int single_inst;
-
- skip_subroutines = arg->data.integer;
- single_inst = arg->next->data.integer;
- count = arg->next->next->data.integer;
-
- if (stop_step)
- step_once (skip_subroutines, single_inst, count - 1);
+ if (error_p)
+ disable_longjmp_breakpoint ();
else
- if (!single_inst || skip_subroutines)
- do_exec_cleanups (ALL_CLEANUPS);
+ {
+ int count;
+ int skip_subroutines;
+ int single_inst;
+
+ skip_subroutines = arg->data.integer;
+ single_inst = arg->next->data.integer;
+ count = arg->next->next->data.integer;
+
+ if (stop_step)
+ step_once (skip_subroutines, single_inst, count - 1);
+ else
+ if (!single_inst || skip_subroutines)
+ disable_longjmp_breakpoint ();
+ }
}
/* Do just one step operation. If count >1 we will have to set up a
step_over_calls = STEP_OVER_ALL;
step_multi = (count > 1);
+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
arg1 =
(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
arg2 =
arg3->next = NULL;
arg3->data.integer = count;
add_intermediate_continuation (step_1_continuation, arg1);
- proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
}
}
called via the cmd_continuation pointer. */
static void
-finish_command_continuation (struct continuation_arg *arg)
+finish_command_continuation (struct continuation_arg *arg, int error_p)
{
struct symbol *function;
struct breakpoint *breakpoint;
function = (struct symbol *) arg->next->data.pointer;
cleanups = (struct cleanup *) arg->next->next->data.pointer;
- if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL
- && function != NULL)
+ if (!error_p)
{
- struct type *value_type;
-
- value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
- if (!value_type)
- internal_error (__FILE__, __LINE__,
- _("finish_command: function has no target type"));
-
- if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
- print_return_value (SYMBOL_TYPE (function), value_type);
+ if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL
+ && function != NULL)
+ {
+ struct type *value_type;
+
+ value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
+ if (!value_type)
+ internal_error (__FILE__, __LINE__,
+ _("finish_command: function has no target type"));
+
+ if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
+ print_return_value (SYMBOL_TYPE (function), value_type);
+ }
}
- do_exec_cleanups (cleanups);
+ delete_breakpoint (breakpoint);
}
/* "finish": Set a temporary breakpoint at the place the selected
breakpoint = set_momentary_breakpoint (sal, get_frame_id (frame), bp_finish);
- if (!target_can_async_p ())
- old_chain = make_cleanup_delete_breakpoint (breakpoint);
- else
- old_chain = make_exec_cleanup_delete_breakpoint (breakpoint);
+ old_chain = make_cleanup_delete_breakpoint (breakpoint);
/* Find the function we will return from. */
proceed_to_finish = 1; /* We want stop_registers, please... */
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
- /* If running asynchronously and the target support asynchronous
- execution, set things up for the rest of the finish command to be
- completed later on, when gdb has detected that the target has
- stopped, in fetch_inferior_event.
- Setup it only after proceed, so that if proceed throws, we don't
- set continuation. */
- if (target_can_async_p ())
- {
- arg1 =
- (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
- arg2 =
- (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
- arg3 =
- (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
- arg1->next = arg2;
- arg2->next = arg3;
- arg3->next = NULL;
- arg1->data.pointer = breakpoint;
- arg2->data.pointer = function;
- arg3->data.pointer = old_chain;
- add_continuation (finish_command_continuation, arg1);
- }
+ arg1 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg2 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg3 =
+ (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+ arg1->next = arg2;
+ arg2->next = arg3;
+ arg3->next = NULL;
+ arg1->data.pointer = breakpoint;
+ arg2->data.pointer = function;
+ arg3->data.pointer = old_chain;
+ add_continuation (finish_command_continuation, arg1);
/* Do this only if not running asynchronously or if the target
cannot do async execution. Otherwise, complete this command when
the target actually stops, in fetch_inferior_event. */
+ discard_cleanups (old_chain);
if (!target_can_async_p ())
- {
- /* Did we stop at our breakpoint? */
- if (bpstat_find_breakpoint (stop_bpstat, breakpoint) != NULL
- && function != NULL)
- {
- struct type *value_type;
-
- value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
- if (!value_type)
- internal_error (__FILE__, __LINE__,
- _("finish_command: function has no target type"));
-
- if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
- print_return_value (SYMBOL_TYPE (function), value_type);
- }
-
- do_cleanups (old_chain);
- }
+ do_all_continuations (0);
}
\f
}
static void
-attach_command_continuation (struct continuation_arg *arg)
+attach_command_continuation (struct continuation_arg *arg, int error_p)
{
char *args;
int from_tty;
if (!async_ecs->wait_some_more)
{
- old_cleanups = make_exec_cleanup (delete_step_resume_breakpoint,
- &step_resume_breakpoint);
-
/* Fill in with reasonable starting values. */
init_execution_control_state (async_ecs);
if (!async_ecs->wait_some_more)
{
- /* Do only the cleanups that have been added by this
- function. Let the continuations for the commands do the rest,
- if there are any. */
- do_exec_cleanups (old_cleanups);
+ delete_step_resume_breakpoint (&step_resume_breakpoint);
+
normal_stop ();
if (step_multi && stop_step)
inferior_event_handler (INF_EXEC_CONTINUE, NULL);
if (current_interpreter != NULL)
{
- do_all_continuations ();
+ do_all_continuations (0);
ui_out_flush (uiout);
if (current_interpreter->procs->suspend_proc
&& !current_interpreter->procs->suspend_proc (current_interpreter->
}
static void
-mi_interpreter_exec_continuation (struct continuation_arg *arg)
+mi_interpreter_exec_continuation (struct continuation_arg *arg, int error_p)
{
bpstat_do_actions (&stop_bpstat);
+ /* It's not clear what to do in the case of errror -- should we assume that
+ the target is stopped, or that it still runs? */
if (!target_executing)
{
fputs_unfiltered ("*stopped", raw_stdout);
fputs_unfiltered ("\n", raw_stdout);
fputs_unfiltered ("(gdb) \n", raw_stdout);
gdb_flush (raw_stdout);
- do_exec_cleanups (ALL_CLEANUPS);
}
else if (target_can_async_p ())
{
const char *args);
static enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty);
-static void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg);
+static void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg,
+ int error_p);
static int register_changed_p (int regnum, struct regcache *,
struct regcache *);
mi_out_put (uiout, raw_stdout);
mi_out_rewind (uiout);
fputs_unfiltered ("\n", raw_stdout);
- do_exec_cleanups (ALL_CLEANUPS);
return MI_CMD_QUIET;
}
static enum mi_cmd_result
mi_cmd_execute (struct mi_parse *parse)
{
+ struct cleanup *cleanup;
+ enum mi_cmd_result r;
free_all_values ();
if (parse->cmd->argv_func != NULL
}
}
last_async_command = xstrdup (parse->token);
- make_exec_cleanup (free_current_contents, &last_async_command);
+ cleanup = make_cleanup (free_current_contents, &last_async_command);
/* FIXME: DELETE THIS! */
if (parse->cmd->args_func != NULL)
- return parse->cmd->args_func (parse->args, 0 /*from_tty */ );
- return parse->cmd->argv_func (parse->command, parse->argv, parse->argc);
+ r = parse->cmd->args_func (parse->args, 0 /*from_tty */ );
+ else
+ r = parse->cmd->argv_func (parse->command, parse->argv, parse->argc);
+ if (target_can_async_p () && target_executing)
+ /* last_async_command will be freed by continuation that
+ all execution command set. */
+ discard_cleanups (cleanup);
+ else
+ do_cleanups (cleanup);
+ return r;
}
else if (parse->cmd->cli.cmd != 0)
{
{
struct cleanup *old_cleanups;
char *run;
- char *async_args;
if (target_can_async_p ())
- {
- async_args = (char *) xmalloc (strlen (args) + 2);
- make_exec_cleanup (free, async_args);
- strcpy (async_args, args);
- strcat (async_args, "&");
- run = xstrprintf ("%s %s", mi, async_args);
- make_exec_cleanup (free, run);
- add_continuation (mi_exec_async_cli_cmd_continuation, NULL);
- old_cleanups = NULL;
- }
+ run = xstrprintf ("%s %s&", mi, args);
else
- {
- run = xstrprintf ("%s %s", mi, args);
- old_cleanups = make_cleanup (xfree, run);
- }
+ run = xstrprintf ("%s %s", mi, args);
+ old_cleanups = make_cleanup (xfree, run);
if (!target_can_async_p ())
{
if (last_async_command)
fputs_unfiltered (last_async_command, raw_stdout);
fputs_unfiltered ("^running\n", raw_stdout);
+
+ /* Ideally, we should be intalling continuation only when
+ the target is already running. However, this will break right now,
+ because continuation installed by the 'finish' command must be after
+ the continuation that prints *stopped. This issue will be
+ fixed soon. */
+ add_continuation (mi_exec_async_cli_cmd_continuation, NULL);
}
execute_command ( /*ui */ run, 0 /*from_tty */ );
- if (!target_can_async_p ())
+ if (target_can_async_p ())
+ {
+ /* If we're not executing, an exception should have been throw. */
+ gdb_assert (target_executing);
+ do_cleanups (old_cleanups);
+ }
+ else
{
/* Do this before doing any printing. It would appear that some
print code leaves garbage around in the buffer. */
print_diff_now (current_command_ts);
fputs_unfiltered ("\n", raw_stdout);
return MI_CMD_QUIET;
- }
+ }
return MI_CMD_DONE;
}
void
-mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg)
+mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg, int error_p)
{
+ /* Assume 'error' means that target is stopped, too. */
if (last_async_command)
fputs_unfiltered (last_async_command, raw_stdout);
fputs_unfiltered ("*stopped", raw_stdout);
fputs_unfiltered ("\n", raw_stdout);
fputs_unfiltered ("(gdb) \n", raw_stdout);
gdb_flush (raw_stdout);
- do_exec_cleanups (ALL_CLEANUPS);
+ if (last_async_command)
+ {
+ free (last_async_command);
+ last_async_command = NULL;
+ }
}
void
are always running synchronously. Or if we have just executed a
command that doesn't start the target. */
static void
-command_line_handler_continuation (struct continuation_arg *arg)
+command_line_handler_continuation (struct continuation_arg *arg, int error)
{
extern int display_time;
extern int display_space;
long time_at_cmd_start = arg->data.longint;
long space_at_cmd_start = arg->next->data.longint;
+ if (error)
+ return;
+
bpstat_do_actions (&stop_bpstat);
if (display_time)
static struct cleanup *cleanup_chain; /* cleaned up after a failed command */
static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */
-static struct cleanup *exec_cleanup_chain; /* cleaned up on each execution command */
/* Pointer to what is left to do for an execution command after the
target stops. Used only in asynchronous mode, by targets that
return make_my_cleanup (&final_cleanup_chain, function, arg);
}
-struct cleanup *
-make_exec_cleanup (make_cleanup_ftype *function, void *arg)
-{
- return make_my_cleanup (&exec_cleanup_chain, function, arg);
-}
-
static void
do_freeargv (void *arg)
{
do_my_cleanups (&final_cleanup_chain, old_chain);
}
-void
-do_exec_cleanups (struct cleanup *old_chain)
-{
- do_my_cleanups (&exec_cleanup_chain, old_chain);
-}
-
static void
do_my_cleanups (struct cleanup **pmy_chain,
struct cleanup *old_chain)
/* Add a continuation to the continuation list, the global list
cmd_continuation. The new continuation will be added at the front.*/
void
-add_continuation (void (*continuation_hook) (struct continuation_arg *),
+add_continuation (void (*continuation_hook) (struct continuation_arg *, int),
struct continuation_arg *arg_list)
{
struct continuation *continuation_ptr;
and do the continuations from there on, instead of using the
global beginning of list as our iteration pointer. */
void
-do_all_continuations (void)
+do_all_continuations (int error)
{
struct continuation *continuation_ptr;
struct continuation *saved_continuation;
/* Work now on the list we have set aside. */
while (continuation_ptr)
{
- (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
+ (continuation_ptr->continuation_hook) (continuation_ptr->arg_list, error);
saved_continuation = continuation_ptr;
continuation_ptr = continuation_ptr->next;
xfree (saved_continuation);
the front. */
void
add_intermediate_continuation (void (*continuation_hook)
- (struct continuation_arg *),
+ (struct continuation_arg *, int),
struct continuation_arg *arg_list)
{
struct continuation *continuation_ptr;
and do the continuations from there on, instead of using the
global beginning of list as our iteration pointer.*/
void
-do_all_intermediate_continuations (void)
+do_all_intermediate_continuations (int error)
{
struct continuation *continuation_ptr;
struct continuation *saved_continuation;
/* Work now on the list we have set aside. */
while (continuation_ptr)
{
- (continuation_ptr->continuation_hook) (continuation_ptr->arg_list);
+ (continuation_ptr->continuation_hook) (continuation_ptr->arg_list, error);
saved_continuation = continuation_ptr;
continuation_ptr = continuation_ptr->next;
xfree (saved_continuation);