home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / unix / unixlib_1 / !UnixLib37_src_sys_c_syslib < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-09  |  5.8 KB  |  238 lines

  1. /****************************************************************************
  2.  *
  3.  * $Source: /unixb/home/unixlib/source/unixlib37/src/sys/c/RCS/syslib,v $
  4.  * $Date: 1996/10/30 21:59:00 $
  5.  * $Revision: 1.4 $
  6.  * $State: Rel $
  7.  * $Author: unixlib $
  8.  *
  9.  * $Log: syslib,v $
  10.  * Revision 1.4  1996/10/30 21:59:00  unixlib
  11.  * Massive changes made by Nick Burret and Peter Burwood.
  12.  *
  13.  * Revision 1.3  1996/07/21 22:12:31  unixlib
  14.  * CL_0001 Nick Burret
  15.  * Improve memory handling. Remove C++ library incompatibilities.
  16.  * Improve file stat routines.
  17.  *
  18.  * Revision 1.2  1996/05/06 09:03:14  unixlib
  19.  * Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
  20.  * Saved for 3.7a release.
  21.  *
  22.  * Revision 1.1  1996/04/19 21:34:24  simon
  23.  * Initial revision
  24.  *
  25.  ***************************************************************************/
  26.  
  27. static const char rcs_id[] = "$Id: syslib,v 1.4 1996/10/30 21:59:00 unixlib Rel $";
  28.  
  29. #include <signal.h>
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <errno.h>
  33. #include <string.h>
  34. #include <ctype.h>
  35. #include <unistd.h>
  36. #include <sys/syslib.h>
  37. #include <sys/os.h>
  38. #include <sys/unix.h>
  39. #include <sys/swis.h>
  40. #include <sys/wait.h>
  41. #include <unixlib/sigstate.h>
  42.  
  43. struct env __Cenv[1] =
  44. {
  45.   {
  46.     {
  47.       {0, 0, 0},        /* MemoryLimit */
  48.       {__h_sigill, 0, 0},    /* Undefined Inst. */
  49.       {__h_sigsegv0, 0, 0},    /* Prefetch Abort */
  50.       {__h_sigsegv1, 0, 0},    /* Data Abort */
  51.       {__h_sigbus, 0, 0},    /* Address Exception */
  52.       {0, 0, 0},        /* Other Exception */
  53.       {__h_error, 0, 0},    /* Error */
  54.       {__h_cback, 0, (void *) __cbreg},        /* CallBack */
  55.       {0, 0, 0},        /* BreakPoint */
  56.       {__h_sigint, 0, 0},    /* Escape */
  57.       {__h_event, 0, 0},    /* Event */
  58.       {__h_exit, 0, 0},        /* Exit */
  59.       {0 /* __h_sigsys */ , 0, 0}    /* Unknown SWI */
  60.     }
  61.   }
  62. };
  63.  
  64. struct env __Oenv[1];
  65.  
  66. struct proc *__u;
  67.  
  68. /* This is the only file that need ever reference main()
  69.    so to prevent possible compiler errors from sources that
  70.    might include <sys/syslib.h> we will have the main()
  71.    declaration here.  */
  72. extern int main (int argc, char *argv[], char **environ);
  73.  
  74. void
  75. _main (void)
  76. {
  77.   register struct env *e;
  78.   register int i;
  79.  
  80.   e = __Oenv;
  81.   for (i = 0; i < 13; i++)
  82.     __rdenv (i, e->h + i);
  83.  
  84.   __h_errbuf = (char *) e->h[6].b;
  85.  
  86.   /* For __uname() - If __uname_dont_pack is set, unset vowel dropping bit */
  87.   if (__uname_dont_pack_ptr && *__uname_dont_pack_ptr)
  88.     __uname_control &= ~__UNAME_DROP_VOWEL;
  89.  
  90.   e = __Cenv;
  91.   for (i = 0; i < 13; i++)
  92.     __wrenv (i, e->h + i);
  93.  
  94.   /* handlers installed */
  95.  
  96.   __fptest ();            /* flag FP presence */
  97. #ifdef DEBUG
  98.   os_print ("Initialising unix\n\r");
  99. #endif
  100.   __unixinit ();        /* initialise UNIX */
  101.   /* Initialise the signal handlers.  */
  102.   __unixlib_signal_initialise ();
  103. #ifdef DEBUG
  104.   os_print ("Initialising system resource limits\n\r");
  105. #endif
  106.   __resource_initialise ();    /* Initialise system resources limits.  */
  107.  
  108.   if (___stdioinit)
  109.     __funcall ((*___stdioinit), ());    /* initialise stdin,stdout & stderr */
  110.  
  111.   if (___do_global_ctors)
  112.     __funcall ((*___do_global_ctors), ());    /* if C++ call constructors */
  113.  
  114.   /* For __uname() - If __uname_dont_pack is set, unset vowel dropping bit */
  115.   if (__uname_dont_pack_ptr && *__uname_dont_pack_ptr)
  116.     __uname_control &= ~4;
  117.  
  118. #ifdef DEBUG
  119.   os_print ("Going main...\r\n");
  120. #endif
  121.   /* Pass the environ variable as a third argument, for compatibility
  122.      with Unix systems.  */
  123.   exit (main (__u->argc, __u->argv, environ));    /* ... ignition */
  124.  
  125. /* not reached */
  126. }
  127.  
  128. void (*__ax[__MAX_AXCNT]) (void);
  129. int __axcnt = 0;
  130.  
  131. void
  132. exit (int r)
  133. {
  134.   register int i;
  135.  
  136.   /* Execute atexit functions in the reverse order of their
  137.      registration.  */
  138.   i = __axcnt;
  139.   while (i)
  140.     {
  141.       i--;
  142.       __funcall ((*__ax[i]), ());
  143.     }
  144.  
  145.   /* Close all open streams, write out buffered output data and
  146.      delete tmpfile() temporary files.  */
  147.   if (___stdioexit)
  148.     __funcall ((*___stdioexit), ());
  149.  
  150.   _exit (__W_EXITCODE(r, 0));
  151. }
  152.  
  153. void
  154. __reset (void)
  155. {
  156.   register int i;
  157.   register struct env *e;
  158.  
  159.   if (__u)
  160.     __unixexit ();        /* shutdown UNIX (close all fds etc.) */
  161.  
  162.   e = __Oenv;
  163.   for (i = 0; i < 13; i++)
  164.     __wrenv (i, e->h + i);
  165. }
  166.  
  167. void
  168. _exit (int r)
  169. {
  170.   /* Interval timers must be stopped otherwise we could crash if they
  171.      are running.  */
  172.   if (__u)
  173.     __stop_itimers ();
  174.  
  175.   /* If we aren't a child process then we can just exit the system.  */
  176.   if (!__u || !__u->status.has_parent || !___vret)
  177.     {
  178.       int regs[10];
  179.  
  180.       __reset ();
  181.  
  182.       /* Bit of a funny one with RISC OS and it's return code limit.
  183.          If the return code exceeds Sys$RCLimit, then RISC OS will
  184.          produce a corrupted error message.  So just return the
  185.          exit status.  */
  186.       r = __WEXITSTATUS(r);
  187.       regs[0] = (int) "Sys$ReturnCode";
  188.       regs[1] = (int) &r;
  189.       regs[2] = 4;
  190.       regs[3] = 0;
  191.       regs[4] = 1;
  192.       os_swi (OS_SetVarVal, regs);
  193. #ifdef DEBUG
  194.       os_print ("Setting return code = ");
  195.       os_prhex (r);
  196.       os_print ("\r\n");
  197. #endif
  198.  
  199.       __exit (r);        /* OS_Exit with return value <r> */
  200.     }
  201.   else
  202.     {
  203.       int time = (int) clock ();
  204.  
  205.       /* Might as well store the time this process has been executing
  206.          for.  */
  207.       __u->usage.ru_utime.tv_sec = time/100;
  208.       __u->usage.ru_utime.tv_usec = (time - ((int)(time / 100) * 100)) * 10000;
  209.       __funcall ((*___vret), (r));
  210.     }
  211. }
  212.  
  213. int
  214. __funcall_error (char *file, int line, unsigned int addr)
  215. {
  216.   char buf[11];
  217.   char *s = buf + 11;
  218.  
  219.   os_print ("fatal error: Attempt to call a function at address below 0x");
  220.   os_prhex ((unsigned int)__base);
  221.   os_print ("\n\ror a function at a non word-aligned address in a UnixLib function.\r\nFile: ");
  222.   os_print (file);
  223.   os_print (", line: ");
  224.   do
  225.     {
  226.       *--s = (line % 10) + '0';
  227.       line /= 10;
  228.     }
  229.   while (line != 0);
  230.   os_print (s);
  231.   os_print (", function address: 0x");
  232.   os_prhex (addr);
  233.   os_nl ();
  234.  
  235.   raise (SIGABRT);
  236.   return 0;
  237. }
  238.