home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / EMXLIB8F.ZIP / EMX / LIB / SYS / INIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-02  |  7.5 KB  |  307 lines

  1. /* sys/init.c (emx+gcc) -- Copyright (c) 1992-1993 by Eberhard Mattes */
  2.  
  3. #include <sys/emx.h>
  4. #include <os2emx.h>
  5. #include <signal.h>
  6. #include <string.h>
  7.  
  8. #define EXTERN
  9. #define INIT(x) = x
  10.  
  11. #include "syscalls.h"
  12. #include "syssig.h"
  13.  
  14. static int arg_size;
  15. static int env_size;
  16. static int argc;
  17. static int envc;
  18. static char **vec;
  19. static char *pool;
  20.  
  21. extern void volatile __init_ret (void *stack);
  22. static void parse_args (const char *src);
  23. static void parse_env (const char *src);
  24. static ULONG _sys_exception (PEXCEPTIONREPORTRECORD report,
  25.     PEXCEPTIONREGISTRATIONRECORD registration, PCONTEXTRECORD context,
  26.     PVOID whatever);
  27.  
  28. #define PUTC(c) BEGIN ++arg_size; if (pool != NULL) *pool++ = (c); END
  29. #define PUTV    BEGIN ++argc; if (vec != NULL) *vec++ = pool; END
  30.  
  31. #define WHITE(c) ((c) == ' ' || (c) == '\t')
  32.  
  33. static void parse_args (const char *src)
  34. {
  35.   int bs, quote;
  36.   char *flag_ptr;
  37.  
  38.   argc = 0; arg_size = 0;
  39.   /* argv[0] */
  40.   PUTC (0x80);
  41.   PUTV;
  42.   for (;;)
  43.     {
  44.       PUTC (*src);
  45.       if (*src == 0)
  46.         break;
  47.       ++src;
  48.     }
  49.   ++src;
  50.   for (;;)
  51.     {
  52.       while (WHITE (*src))
  53.         ++src;
  54.       if (*src == 0)
  55.         break;
  56.       flag_ptr = pool;
  57.       PUTC (0x80);
  58.       PUTV;
  59.       bs = 0; quote = 0;
  60.       for (;;)
  61.         {
  62.           if (*src == '"')
  63.             {
  64.               while (bs >= 2)
  65.                 {
  66.                   PUTC ('\\');
  67.                   bs -= 2;
  68.                 }
  69.               if (bs & 1)
  70.                 PUTC ('"');
  71.               else
  72.                 {
  73.                   quote = !quote;
  74.                   if (flag_ptr != NULL)
  75.                     *flag_ptr |= 1;
  76.                 }
  77.               bs = 0;
  78.             }
  79.           else if (*src == '\\')
  80.             ++bs;
  81.           else
  82.             {
  83.               while (bs != 0)
  84.                 {
  85.                   PUTC ('\\');
  86.                   --bs;
  87.                 }
  88.               if (*src == 0 || (WHITE (*src) && !quote))
  89.                 break;
  90.               PUTC (*src);
  91.             }
  92.           ++src;
  93.         }
  94.       PUTC (0);
  95.     }
  96. }
  97.  
  98.  
  99. static void parse_env (const char *src)
  100. {
  101.   envc = 0; env_size = 0;
  102.   while (*src != 0)
  103.     {
  104.       ++envc;
  105.       if (vec != NULL)
  106.         *vec++ = pool;
  107.       for (;;)
  108.         {
  109.           ++env_size;
  110.           if (pool != NULL)
  111.             *pool++ = *src;
  112.           if (*src == 0)
  113.             break;
  114.           ++src;
  115.         }
  116.       ++src;
  117.     }
  118. }
  119.  
  120.  
  121.  
  122. void __init (void)
  123. {
  124.   ULONG rc;
  125.   PTIB ptib;
  126.   PPIB ppib;
  127.   void *stack;
  128.   int n;
  129.   ULONG times;
  130.  
  131.   _sys_get_clock (&_sys_clock0_lo, &_sys_clock0_hi, &_sys_clock0_ms);
  132.   rc = DosGetInfoBlocks (&ptib, &ppib);
  133.   if (rc != 0)
  134.     DosExit (EXIT_PROCESS, 255);
  135.   vec = NULL; pool = NULL;
  136.   parse_env (ppib->pib_pchenv);
  137.   parse_args (ppib->pib_pchcmd);
  138.   n = arg_size + env_size + (argc+1+envc+1) * sizeof (char *);
  139.   if (n & 3)
  140.     n = (n | 3) + 1;            /* alignment for EXCEPTIONREGISTRATIONRECORD */
  141.   stack = alloca (n + sizeof (EXCEPTIONREGISTRATIONRECORD));
  142.   _sys_xreg = stack + n;
  143.   vec = stack;
  144.   pool = (char *)(vec + argc+1+envc+1);
  145.   parse_env (ppib->pib_pchenv);
  146.   *vec++ = NULL;               /* empty environment */
  147.   parse_args (ppib->pib_pchcmd);
  148.   *vec++ = NULL;
  149.   _sys_heap_size = 0x2000000;
  150.   rc = DosAllocMem (&_sys_heap_base, _sys_heap_size, PAG_READ|PAG_WRITE);
  151.   if (rc != 0)
  152.     DosExit (EXIT_PROCESS, 255);
  153.   _sys_heap_brk = _sys_heap_base;
  154.   for (n = 0; n < NSIG; ++n)
  155.     {
  156.       _sys_sig_handlers[n] = SIG_DFL;
  157.       _sys_sig_ack_req[n] = 0;
  158.       _sys_sig_pending[n] = 0;
  159.     }
  160.   _sys_xreg->prev_structure = (void *)0xffffffff;
  161.   _sys_xreg->ExceptionHandler = _sys_exception;
  162.   rc = DosSetExceptionHandler (_sys_xreg);
  163.   if (rc != 0)
  164.     DosExit (EXIT_PROCESS, 255);
  165.   DosSetSignalExceptionFocus (SIG_SETFOCUS, ×);
  166.   /* Fails for PM programs, error code 303 */
  167.   __init_ret (stack);
  168. }
  169.  
  170.  
  171. static const char * const sig_name[NSIG] =
  172. {
  173.   NULL,
  174.   "SIGHUP",
  175.   "SIGINT",
  176.   "SIGQUIT",
  177.   "SIGILL",
  178.   "SIGTRAP",
  179.   "SIGABRT",
  180.   "SIGEMT",
  181.   "SIGFPE",
  182.   "SIGKILL",
  183.   "SIGBUS",
  184.   "SIGSEGV",
  185.   "SIGSYS",
  186.   "SIGPIPE",
  187.   "SIGALRM",
  188.   "SIGTERM",
  189.   "SIGCLD",
  190.   "SIGBREAK"
  191. };
  192.  
  193.  
  194. static void say (const char *msg)
  195. {
  196.   __write (2, msg, strlen (msg));
  197. };
  198.  
  199.  
  200. static ULONG _sys_signal (int sig)
  201. {
  202.   if (sig < 1 || sig >= NSIG)
  203.     return (XCPT_CONTINUE_SEARCH);
  204.   if (_sys_sig_handlers[sig] == SIG_IGN)
  205.     return (XCPT_CONTINUE_EXECUTION);
  206.   else if (_sys_sig_handlers[sig] == SIG_DFL)
  207.     {
  208.       if (sig == SIGCLD)
  209.         return (XCPT_CONTINUE_EXECUTION);
  210.       if (sig == SIGABRT)
  211.         say ("\r\nAbnormal program termination\r\n");
  212.       else
  213.         {
  214.           say ("\r\nProcess terminated by ");
  215.           say (sig_name[sig]);
  216.           say ("\r\n");
  217.         }
  218.       while (1)
  219.         DosExit (EXIT_PROCESS, 3);
  220.     }
  221.   else
  222.     {
  223.       _sys_sig_handlers[sig] (sig);
  224.       return (XCPT_CONTINUE_EXECUTION);
  225.     }
  226. }
  227.  
  228.  
  229. static ULONG _sys_exception (PEXCEPTIONREPORTRECORD report,
  230.                              PEXCEPTIONREGISTRATIONRECORD registration,
  231.                              PCONTEXTRECORD context,
  232.                              PVOID whatever)
  233. {
  234.   if (report->fHandlerFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
  235.     return (XCPT_CONTINUE_SEARCH);
  236.   switch (report->ExceptionNum)
  237.     {
  238.     case XCPT_SIGNAL:
  239.       if (report->cParameters >= 1)
  240.         {
  241.           if (report->ExceptionInfo[0] == XCPT_SIGNAL_INTR)
  242.             return (_sys_signal (SIGINT));
  243.           else if (report->ExceptionInfo[0] == XCPT_SIGNAL_BREAK)
  244.             return (_sys_signal (SIGBREAK));
  245.         }
  246.       break;
  247.     case SIG2X (SIGHUP):
  248.       return (_sys_signal (SIGHUP));
  249.     case SIG2X (SIGINT):
  250.       return (_sys_signal (SIGINT));
  251.     case SIG2X (SIGQUIT):
  252.       return (_sys_signal (SIGQUIT));
  253.     case SIG2X (SIGILL):
  254.       return (_sys_signal (SIGILL));
  255.     case SIG2X (SIGTRAP):
  256.       return (_sys_signal (SIGTRAP));
  257.     case SIG2X (SIGABRT):
  258.       return (_sys_signal (SIGABRT));
  259.     case SIG2X (SIGEMT):
  260.       return (_sys_signal (SIGEMT));
  261.     case SIG2X (SIGFPE):
  262.       return (_sys_signal (SIGFPE));
  263.     case SIG2X (SIGKILL):
  264.       return (_sys_signal (SIGKILL));
  265.     case SIG2X (SIGBUS):
  266.       return (_sys_signal (SIGBUS));
  267.     case SIG2X (SIGSEGV):
  268.       return (_sys_signal (SIGSEGV));
  269.     case SIG2X (SIGSYS):
  270.       return (_sys_signal (SIGSYS));
  271.     case SIG2X (SIGPIPE):
  272.       return (_sys_signal (SIGPIPE));
  273.     case SIG2X (SIGALRM):
  274.       return (_sys_signal (SIGALRM));
  275.     case SIG2X (SIGTERM):
  276.       return (_sys_signal (SIGTERM));
  277.     case SIG2X (SIGCLD):
  278.       return (_sys_signal (SIGCLD));
  279.     case SIG2X (SIGBREAK):
  280.       return (_sys_signal (SIGBREAK));
  281.     }
  282.   return (XCPT_CONTINUE_SEARCH);
  283. }
  284.  
  285.  
  286. void _sys_get_clock (unsigned long *lo, unsigned long *hi, unsigned long *ms)
  287. {
  288.   ULONG val_lo, val_hi, val_ms, tmp_lo, tmp_hi;
  289.  
  290.   do
  291.     {
  292.       DosQuerySysInfo (QSV_TIME_HIGH, QSV_TIME_HIGH,
  293.                        &val_hi, sizeof (val_hi));
  294.       DosQuerySysInfo (QSV_TIME_LOW, QSV_TIME_LOW,
  295.                        &val_lo, sizeof (val_lo));
  296.       DosQuerySysInfo (QSV_MS_COUNT, QSV_MS_COUNT,
  297.                        &val_ms, sizeof (val_ms));
  298.       DosQuerySysInfo (QSV_TIME_LOW, QSV_TIME_LOW,
  299.                        &tmp_lo, sizeof (tmp_lo));
  300.       DosQuerySysInfo (QSV_TIME_HIGH, QSV_TIME_HIGH,
  301.                        &tmp_hi, sizeof (tmp_hi));
  302.     } while (val_lo != tmp_lo || val_hi != tmp_hi);
  303.   *lo = val_lo;
  304.   *hi = val_hi;
  305.   *ms = val_ms;
  306. }
  307.