home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * $Source: /unixb/home/unixlib/source/unixlib37/src/sys/c/RCS/syslib,v $
- * $Date: 1996/10/30 21:59:00 $
- * $Revision: 1.4 $
- * $State: Rel $
- * $Author: unixlib $
- *
- * $Log: syslib,v $
- * Revision 1.4 1996/10/30 21:59:00 unixlib
- * Massive changes made by Nick Burret and Peter Burwood.
- *
- * Revision 1.3 1996/07/21 22:12:31 unixlib
- * CL_0001 Nick Burret
- * Improve memory handling. Remove C++ library incompatibilities.
- * Improve file stat routines.
- *
- * Revision 1.2 1996/05/06 09:03:14 unixlib
- * Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
- * Saved for 3.7a release.
- *
- * Revision 1.1 1996/04/19 21:34:24 simon
- * Initial revision
- *
- ***************************************************************************/
-
- static const char rcs_id[] = "$Id: syslib,v 1.4 1996/10/30 21:59:00 unixlib Rel $";
-
- #include <signal.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <ctype.h>
- #include <unistd.h>
- #include <sys/syslib.h>
- #include <sys/os.h>
- #include <sys/unix.h>
- #include <sys/swis.h>
- #include <sys/wait.h>
- #include <unixlib/sigstate.h>
-
- struct env __Cenv[1] =
- {
- {
- {
- {0, 0, 0}, /* MemoryLimit */
- {__h_sigill, 0, 0}, /* Undefined Inst. */
- {__h_sigsegv0, 0, 0}, /* Prefetch Abort */
- {__h_sigsegv1, 0, 0}, /* Data Abort */
- {__h_sigbus, 0, 0}, /* Address Exception */
- {0, 0, 0}, /* Other Exception */
- {__h_error, 0, 0}, /* Error */
- {__h_cback, 0, (void *) __cbreg}, /* CallBack */
- {0, 0, 0}, /* BreakPoint */
- {__h_sigint, 0, 0}, /* Escape */
- {__h_event, 0, 0}, /* Event */
- {__h_exit, 0, 0}, /* Exit */
- {0 /* __h_sigsys */ , 0, 0} /* Unknown SWI */
- }
- }
- };
-
- struct env __Oenv[1];
-
- struct proc *__u;
-
- /* This is the only file that need ever reference main()
- so to prevent possible compiler errors from sources that
- might include <sys/syslib.h> we will have the main()
- declaration here. */
- extern int main (int argc, char *argv[], char **environ);
-
- void
- _main (void)
- {
- register struct env *e;
- register int i;
-
- e = __Oenv;
- for (i = 0; i < 13; i++)
- __rdenv (i, e->h + i);
-
- __h_errbuf = (char *) e->h[6].b;
-
- /* For __uname() - If __uname_dont_pack is set, unset vowel dropping bit */
- if (__uname_dont_pack_ptr && *__uname_dont_pack_ptr)
- __uname_control &= ~__UNAME_DROP_VOWEL;
-
- e = __Cenv;
- for (i = 0; i < 13; i++)
- __wrenv (i, e->h + i);
-
- /* handlers installed */
-
- __fptest (); /* flag FP presence */
- #ifdef DEBUG
- os_print ("Initialising unix\n\r");
- #endif
- __unixinit (); /* initialise UNIX */
- /* Initialise the signal handlers. */
- __unixlib_signal_initialise ();
- #ifdef DEBUG
- os_print ("Initialising system resource limits\n\r");
- #endif
- __resource_initialise (); /* Initialise system resources limits. */
-
- if (___stdioinit)
- __funcall ((*___stdioinit), ()); /* initialise stdin,stdout & stderr */
-
- if (___do_global_ctors)
- __funcall ((*___do_global_ctors), ()); /* if C++ call constructors */
-
- /* For __uname() - If __uname_dont_pack is set, unset vowel dropping bit */
- if (__uname_dont_pack_ptr && *__uname_dont_pack_ptr)
- __uname_control &= ~4;
-
- #ifdef DEBUG
- os_print ("Going main...\r\n");
- #endif
- /* Pass the environ variable as a third argument, for compatibility
- with Unix systems. */
- exit (main (__u->argc, __u->argv, environ)); /* ... ignition */
-
- /* not reached */
- }
-
- void (*__ax[__MAX_AXCNT]) (void);
- int __axcnt = 0;
-
- void
- exit (int r)
- {
- register int i;
-
- /* Execute atexit functions in the reverse order of their
- registration. */
- i = __axcnt;
- while (i)
- {
- i--;
- __funcall ((*__ax[i]), ());
- }
-
- /* Close all open streams, write out buffered output data and
- delete tmpfile() temporary files. */
- if (___stdioexit)
- __funcall ((*___stdioexit), ());
-
- _exit (__W_EXITCODE(r, 0));
- }
-
- void
- __reset (void)
- {
- register int i;
- register struct env *e;
-
- if (__u)
- __unixexit (); /* shutdown UNIX (close all fds etc.) */
-
- e = __Oenv;
- for (i = 0; i < 13; i++)
- __wrenv (i, e->h + i);
- }
-
- void
- _exit (int r)
- {
- /* Interval timers must be stopped otherwise we could crash if they
- are running. */
- if (__u)
- __stop_itimers ();
-
- /* If we aren't a child process then we can just exit the system. */
- if (!__u || !__u->status.has_parent || !___vret)
- {
- int regs[10];
-
- __reset ();
-
- /* Bit of a funny one with RISC OS and it's return code limit.
- If the return code exceeds Sys$RCLimit, then RISC OS will
- produce a corrupted error message. So just return the
- exit status. */
- r = __WEXITSTATUS(r);
- regs[0] = (int) "Sys$ReturnCode";
- regs[1] = (int) &r;
- regs[2] = 4;
- regs[3] = 0;
- regs[4] = 1;
- os_swi (OS_SetVarVal, regs);
- #ifdef DEBUG
- os_print ("Setting return code = ");
- os_prhex (r);
- os_print ("\r\n");
- #endif
-
- __exit (r); /* OS_Exit with return value <r> */
- }
- else
- {
- int time = (int) clock ();
-
- /* Might as well store the time this process has been executing
- for. */
- __u->usage.ru_utime.tv_sec = time/100;
- __u->usage.ru_utime.tv_usec = (time - ((int)(time / 100) * 100)) * 10000;
- __funcall ((*___vret), (r));
- }
- }
-
- int
- __funcall_error (char *file, int line, unsigned int addr)
- {
- char buf[11];
- char *s = buf + 11;
-
- os_print ("fatal error: Attempt to call a function at address below 0x");
- os_prhex ((unsigned int)__base);
- os_print ("\n\ror a function at a non word-aligned address in a UnixLib function.\r\nFile: ");
- os_print (file);
- os_print (", line: ");
- do
- {
- *--s = (line % 10) + '0';
- line /= 10;
- }
- while (line != 0);
- os_print (s);
- os_print (", function address: 0x");
- os_prhex (addr);
- os_nl ();
-
- raise (SIGABRT);
- return 0;
- }
-