summaryrefslogtreecommitdiff
path: root/unwind_prot.c
diff options
context:
space:
mode:
Diffstat (limited to 'unwind_prot.c')
-rw-r--r--unwind_prot.c71
1 files changed, 46 insertions, 25 deletions
diff --git a/unwind_prot.c b/unwind_prot.c
index 60e911dd..628845c5 100644
--- a/unwind_prot.c
+++ b/unwind_prot.c
@@ -55,10 +55,13 @@ typedef struct {
int size;
} SAVED_VAR;
-static void unwind_frame_discard_internal (), unwind_frame_run_internal ();
-static void add_unwind_protect_internal (), remove_unwind_protect_internal ();
-static void run_unwind_protects_internal (), without_interrupts ();
-
+static void without_interrupts ();
+static void unwind_frame_discard_internal ();
+static void unwind_frame_run_internal ();
+static void add_unwind_protect_internal ();
+static void remove_unwind_protect_internal ();
+static void run_unwind_protects_internal ();
+static void clear_unwind_protects_internal ();
static void restore_variable ();
static void discard_saved_var ();
@@ -137,9 +140,19 @@ run_unwind_protects ()
(run_unwind_protects_internal, (char *)NULL, (char *)NULL);
}
+/* Erase the unwind-protect list. If flags is 1, free the elements. */
+void
+clear_unwind_protect_list (flags)
+ int flags;
+{
+ if (unwind_protect_list)
+ without_interrupts
+ (clear_unwind_protects_internal, (char *)flags, (char *)NULL);
+}
+
/* **************************************************************** */
/* */
-/* The Actual Functions */
+/* The Actual Functions */
/* */
/* **************************************************************** */
@@ -158,7 +171,8 @@ add_unwind_protect_internal (cleanup, arg)
}
static void
-remove_unwind_protect_internal ()
+remove_unwind_protect_internal (ignore1, ignore2)
+ char *ignore1, *ignore2;
{
UNWIND_ELT *elt;
@@ -173,7 +187,8 @@ remove_unwind_protect_internal ()
}
static void
-run_unwind_protects_internal ()
+run_unwind_protects_internal (ignore1, ignore2)
+ char *ignore1, *ignore2;
{
UNWIND_ELT *t, *elt = unwind_protect_list;
@@ -194,8 +209,23 @@ run_unwind_protects_internal ()
}
static void
-unwind_frame_discard_internal (tag)
- char *tag;
+clear_unwind_protects_internal (flag, ignore)
+ char *flag, *ignore;
+{
+ int free_elts = (int)flag;
+ UNWIND_ELT *elt;
+
+ if (free_elts != 0 && unwind_protect_list)
+ {
+ while (unwind_protect_list)
+ remove_unwind_protect_internal ((char *)NULL, (char *)NULL);
+ }
+ unwind_protect_list = (UNWIND_ELT *)NULL;
+}
+
+static void
+unwind_frame_discard_internal (tag, ignore)
+ char *tag, *ignore;
{
UNWIND_ELT *elt;
@@ -208,18 +238,18 @@ unwind_frame_discard_internal (tag)
break;
}
else if (elt->cleanup && elt->cleanup == (Function *)restore_variable)
- {
- discard_saved_var ((SAVED_VAR *)elt->arg);
- free (elt);
- }
+ {
+ discard_saved_var ((SAVED_VAR *)elt->arg);
+ free (elt);
+ }
else
free (elt);
}
}
static void
-unwind_frame_run_internal (tag)
- char *tag;
+unwind_frame_run_internal (tag, ignore)
+ char *tag, *ignore;
{
UNWIND_ELT *elt;
@@ -290,17 +320,8 @@ unwind_protect_var (var, value, size)
s->variable = var;
if (size != sizeof (int))
{
- /* There is a problem here when VALUE is 0. This tries to copy the
- first SIZE bytes starting at memory location 0 into
- s->desired_setting. There is no guarantee that these bytes are
- 0, or make a valid null pointer. We can try to bzero the space,
- or just save it as 0 (or (void *)0). If we do the latter, make
- sure restore_variable is changed to understand it. */
s->desired_setting = (char *)xmalloc (size);
- if (value == 0)
- bzero ((char *)s->desired_setting, size);
- else
- FASTCOPY (value, (char *)s->desired_setting, size);
+ FASTCOPY (value, (char *)s->desired_setting, size);
}
else
s->desired_setting = value;