/* STARTUP PROCEDURE FOR UNIX FORTRAN PROGRAMS */

#include "f2c.h"
#include "stdio.h"
#include "signal1.h"

#ifndef SIGIOT
#ifdef SIGABRT
#define SIGIOT SIGABRT
#endif
#endif

#ifndef KR_headers
#undef VOID
#include "stdlib.h"
#endif

#ifndef VOID
#define VOID void
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef NO__STDC
#define ONEXIT onexit
extern VOID f_exit();
#else
#ifndef KR_headers
extern void f_exit(void);
#ifndef NO_ONEXIT
#define ONEXIT atexit
extern int atexit(void (*)(void));
#endif
#else
#ifndef NO_ONEXIT
#define ONEXIT onexit
extern VOID f_exit();
#endif
#endif
#endif

#ifdef KR_headers
extern VOID f_init(), sig_die();
extern int __Omni_FortranEntryPoint_();
#define Int /* int */
#else
extern void f_init(void), sig_die(char*, int);
extern int __Omni_FortranEntryPoint_(void);
#define Int int
#endif

static VOID sigfdie(Sigarg)
{
Use_Sigarg;
sig_die("Floating Exception", 1);
}


static VOID sigidie(Sigarg)
{
Use_Sigarg;
sig_die("IOT Trap", 1);
}

#ifdef SIGQUIT
static VOID sigqdie(Sigarg)
{
Use_Sigarg;
sig_die("Quit signal", 1);
}
#endif


static VOID sigindie(Sigarg)
{
Use_Sigarg;
sig_die("Interrupt", 0);
}

static VOID sigtdie(Sigarg)
{
Use_Sigarg;
sig_die("Killed", 0);
}

#ifdef SIGTRAP
static VOID sigtrdie(Sigarg)
{
Use_Sigarg;
sig_die("Trace trap", 1);
}
#endif


int xargc;
char **xargv;

#ifdef __cplusplus
	}
#endif

#ifdef OMNI_OS_SOLARIS
#define NEED_TO_REEXEC
#endif /* OMNI_OS_SOLARIS */

static int
checkStack()
{
#ifdef OMNI_OS_CYGWIN32
    /* Have no getrlim() :< */
    return 0;
#else
    struct rlimit limit, nLimit;

    if (getrlimit(RLIMIT_STACK, &limit) < 0) {
	return 0;
    }
    if (limit.rlim_cur != limit.rlim_max) {
#ifdef OMNI_OS_LINUX
	/*
	 * In this case on Linux, calling setrlimit() reset the stack size B<
	 * Looser.
	 */
	return 0;
#endif /* OMNI_OS_LINUX */
	nLimit.rlim_cur = limit.rlim_max;
	nLimit.rlim_max = limit.rlim_max;
	if (setrlimit(RLIMIT_STACK, &nLimit) < 0) {
	    return 0;
	} else {
#ifdef NEED_TO_REEXEC
	    return 1;
#else
	    return 0;
#endif /* NEED_TO_REEXEC */
	}
    } else {
	return 0;
    }
#endif /* OMNI_OS_CYGWIN32 */
}


static void
#ifdef KR_header
__reStartMe(argc, argv)
     int argc;
     char *argv[];
#else
__reStartMe(int argc, char **argv)
#endif /* KR_header */
{
    if (checkStack() == 1) {
	fprintf(stderr, "ompf77 runtime: Maximize stack size and restart %s. If you don't want to see this message, just unlimit the stack size by issuing \"unlimit\"(csh) or \"ulimit -s 'a big number like 2gb'\"(sh).\n", argv[0]);
	fflush(stderr);
	execvp(argv[0], argv);
    }
}


int
#ifdef KR_headers
main(argc, argv) int argc; char **argv;
#else
main(int argc, char **argv)
#endif
{
#ifdef CALL_OMP_INIT
extern void _ompc_init _ANSI_ARGS_((int argc,char *argv[]));
extern void _ompc_terminate _ANSI_ARGS_((int exitcode));
#endif /* CALL_OMP_INIT */
extern void __Omni_FortranEntryPoint _ANSI_ARGS_((void));
extern void _ompf77_IO_init _ANSI_ARGS_((void));
__reStartMe(argc, argv);
xargc = argc;
xargv = argv;
signal1(SIGFPE, sigfdie);	/* ignore underflow, enable overflow */
#ifdef SIGIOT
signal1(SIGIOT, sigidie);
#endif
#ifdef SIGTRAP
signal1(SIGTRAP, sigtrdie);
#endif
#ifdef SIGQUIT
if(signal1(SIGQUIT,sigqdie) == SIG_IGN)
	signal1(SIGQUIT, SIG_IGN);
#endif
if(signal1(SIGINT, sigindie) == SIG_IGN)
	signal1(SIGINT, SIG_IGN);
signal1(SIGTERM,sigtdie);

#ifdef pdp11
	ldfps(01200); /* detect overflow as an exception */
#endif
f_init();
#ifndef NO_ONEXIT
ONEXIT(f_exit);
#endif
#ifdef CALL_OMP_INIT
_ompc_init(argc,argv);
#endif /* CALL_OMP_INIT */
_ompf77_IO_init();
(void)__Omni_FortranEntryPoint();
#ifdef NO_ONEXIT
f_exit();
#endif
#ifdef CALL_OMP_INIT
_ompc_terminate (0);
#endif /* CALL_OMP_INIT */
exit(0);	/* exit(0) rather than return(0) to bypass Cray bug */
return 0;	/* For compilers that complain of missing return values; */
		/* others will complain that this is unreachable code. */
}
