
#define SAVE_RESULT2

#include <exec/types.h>
#include <exec/libraries.h>
#include <libraries/dos.h>
#ifdef SAVE_RESULT2
#include <libraries/dosextens.h>
#endif
#include <functions.h>

#include <stdlib.h>
#include <fcntl.h>

#include "atexit.h"

extern struct Library *DOSBase;
extern struct Library *MathIeeeDoubBasBase;
extern struct Library *MathIeeeDoubTransBase;

extern short _numdev;
extern struct _device *_devtab;

extern _VOLATILE void _exit (LONG);

struct atexit_block *__atexit_root;

void (*__close_imain) (void);
void (*__fcloseall) (void);
void (*__freeall) (void);


_VOLATILE void
exit (int rc)
{
  int fd;
#ifdef SAVE_RESULT2
  struct Process *pr;
  LONG result2;

  /* Save pr_Result2 so that any cleanup code does not disturb it. */
  pr = (struct Process *) FindTask (NULL);
  result2 = pr->pr_Result2;
#endif

  while (__atexit_root)
    {
      int i;
      void (**func) (void);
      i = __atexit_root->next_slot;
      func = &__atexit_root->functions[i];
      while (i-- > 0)
	(*--func) ();
      __atexit_root = __atexit_root->next;
    }

  if (__close_imain)
    (*__close_imain) ();

  if (__fcloseall)
    (*__fcloseall) ();

  if (_devtab != 0)
    {
      for (fd = 0; fd < _numdev; ++fd)
        close (fd);
      free (_devtab);
    }

  if (__freeall)
    (*__freeall) ();

  if (MathIeeeDoubBasBase)
    CloseLibrary (MathIeeeDoubBasBase);

  if (MathIeeeDoubTransBase)
    CloseLibrary (MathIeeeDoubTransBase);

  if (DOSBase)
    CloseLibrary (DOSBase);

#ifdef SAVE_RESULT2
  result2 = pr->pr_Result2;
#endif

  _exit ((LONG) rc);
}
