DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T u

⟦46aac685e⟧ TextFile

    Length: 4357 (0x1105)
    Types: TextFile
    Names: »unwind_prot.c«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦ca1f037a2⟧ »./bash-1.04.tar.Z« 
        └─⟦46465a4db⟧ 
            └─⟦this⟧ »bash-1.04/unwind_prot.c« 

TextFile

/* I can't stand it anymore!  Please can't we just write the
   whole Unix system in lisp or something? */

/* Copyright (C) 1987,1989 Free Software Foundation, Inc.

This file is part of GNU Bash, the Bourne Again SHell.

Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 1, or (at your option) any later
version.

Bash is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING.  If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */

/* **************************************************************** */
/*								    */
/*		      Unwind Protection Scheme for Bash		    */
/*								    */
/* **************************************************************** */

#include <sys/signal.h>
#include "config.h"
#include "general.h"

/* If CLEANUP is null, then ARG contains a tag to throw back to. */
typedef struct _uwp {
  struct _uwp *next;
  Function *cleanup;
  char *arg;
} UNWIND_ELT;

static UNWIND_ELT *unwind_protect_list = (UNWIND_ELT *)NULL;

/* Run a function without interrupts. */
without_interrupts (function, arg1, arg2)
     Function *function;
     VOID *arg1, *arg2;
{
  SigHandler *old_int;

  old_int = (SigHandler *)signal (SIGINT, SIG_IGN);
  (*function)(arg1, arg2);
  signal (SIGINT, old_int);
}

/* Start the beginning of a region. */
begin_unwind_frame (tag)
     char *tag;
{
  add_unwind_protect ((Function *)NULL, tag);
}

/* Discard the unwind protects back to TAG. */
discard_unwind_frame (tag)
     char *tag;
{
  int unwind_frame_discard_internal ();

  without_interrupts (unwind_frame_discard_internal, tag);
}

/* Run the unwind protects back to TAG. */
run_unwind_frame (tag)
     char *tag;
{
  int unwind_frame_run_internal ();
  without_interrupts (unwind_frame_run_internal, tag);
}

/* Add the function CLEANUP with ARG to the list of unwindable things. */
add_unwind_protect (cleanup, arg)
     Function *cleanup;
     char *arg;
{
  int add_unwind_protect_internal ();
  without_interrupts (add_unwind_protect_internal, cleanup, arg);
}

/* Remove the top unwind protect from the list. */
remove_unwind_protect ()
{
  int remove_unwind_protect_internal ();
  without_interrupts (remove_unwind_protect_internal);
}

/* Run the list of cleanup functions in unwind_protect_list. */
run_unwind_protects ()
{
  int run_unwind_protects_internal ();
  without_interrupts (run_unwind_protects_internal);
}

/* **************************************************************** */
/*								    */
/*                        The Actual Functions                 	    */
/*								    */
/* **************************************************************** */

add_unwind_protect_internal (cleanup, arg)
     Function *cleanup;
     char *arg;
{
  UNWIND_ELT *elt;

  elt = (UNWIND_ELT *)xmalloc (sizeof (UNWIND_ELT));
  elt->cleanup = cleanup;
  elt->arg = arg;
  elt->next = unwind_protect_list;
  unwind_protect_list = elt;
}

remove_unwind_protect_internal ()
{
  UNWIND_ELT *elt = unwind_protect_list;

  if (elt)
    {
      unwind_protect_list = unwind_protect_list->next;
      free (elt);
    }
}

run_unwind_protects_internal ()
{
  UNWIND_ELT *t, *elt = unwind_protect_list;

  while (elt)
    {
      (*(elt->cleanup)) (elt->arg);
      t = elt;
      elt = elt->next;
      free (t);
    }
}

unwind_frame_discard_internal (tag)
     char *tag;
{
  UNWIND_ELT *elt;

  while (elt = unwind_protect_list)
    {
      unwind_protect_list = unwind_protect_list->next;
      if (!elt->cleanup && strcmp (elt->arg, tag) == 0)
	{
	  free (elt);
	  break;
	}
      else
	free (elt);
    }
}

unwind_frame_run_internal (tag)
     char *tag;
{
  UNWIND_ELT *elt;

  while (elt = unwind_protect_list)
    {
      unwind_protect_list = elt->next;

      /* If tag, then compare. */
      if (!elt->cleanup)
	{
	  if (strcmp (elt->arg, tag) == 0)
	    {
	      free (elt);
	      break;
	    }
	  free (elt);
	  continue;
	}
      else
	{
	  (*(elt->cleanup)) (elt->arg);
	  free (elt);
	}
    }
}