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

  1. /* sys/spawnve.c (emx+gcc) -- Copyright (c) 1992-1993 by Eberhard Mattes */
  2.  
  3. #include <sys/emx.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <process.h>
  7. #include <errno.h>
  8. #include <os2emx.h>
  9. #include "syscalls.h"
  10.  
  11. #define ADD(n)  \
  12.   while (arg_size + n > arg_alloc) \
  13.     { \
  14.       arg_alloc += 512; \
  15.       arg_buf = realloc (arg_buf, arg_alloc); \
  16.       if (arg_buf == NULL) \
  17.         { \
  18.           errno = ENOMEM; \
  19.           return (-1); \
  20.         } \
  21.       arg_ptr = arg_buf + arg_size; \
  22.     }
  23.  
  24. int __spawnve (struct _new_proc *np)
  25. {
  26.   ULONG rc;
  27.   ULONG exec_flag;
  28.   RESULTCODES res;
  29.   char obj[40], *arg_ptr, *arg_buf;
  30.   char *pgm_name;
  31.   const char *src;
  32.   size_t arg_size, arg_alloc, len;
  33.   int i, quote, bs;
  34.  
  35.   arg_buf = NULL; arg_alloc = 0; arg_size = 0; arg_ptr = NULL;
  36.   switch (np->mode & 0xff)
  37.     {
  38.     case P_WAIT:
  39.       exec_flag = EXEC_SYNC;
  40.       break;
  41.     case P_NOWAIT:
  42.       exec_flag = EXEC_ASYNCRESULT;
  43.       break;
  44.     case P_OVERLAY:
  45.       exec_flag = EXEC_ASYNC;
  46.       break;
  47.     default:
  48.       errno = EINVAL;
  49.       return (-1);
  50.     }
  51.   pgm_name = alloca (strlen ((const char *)np->fname_off) + 5);
  52.   strcpy (pgm_name, (const char *)np->fname_off);
  53.   _defext (pgm_name, "exe");
  54.   src = (const char *)np->arg_off;
  55.   if (np->arg_count > 0)
  56.     {
  57.       ++src;                    /* skip flags byte */
  58.       len = strlen (src) + 1;
  59.       ADD (len);
  60.       memcpy (arg_ptr, src, len);
  61.       arg_ptr += len; src += len;
  62.     }
  63.   for (i = 1; i < np->arg_count; ++i)
  64.     {
  65.       if (i > 1)
  66.         {
  67.           ADD (1);
  68.           *arg_ptr++ = ' ';
  69.         }
  70.       ++src;                    /* skip flags byte */
  71.       quote = (*src == 0 || strpbrk (src, " \t") != NULL);
  72.       if (quote)
  73.         {
  74.           ADD (1);
  75.           *arg_ptr++ = '"';
  76.         }
  77.       bs = 0;
  78.       while (*src != 0)
  79.         {
  80.           if (*src == '"')
  81.             {
  82.               ++bs;
  83.               ADD (bs);
  84.               memset (arg_ptr, '\\', bs);
  85.               bs = 0;
  86.             }
  87.           else if (*src == '\\')
  88.             ++bs;
  89.           else
  90.             bs = 0;
  91.           ADD (1);
  92.           *arg_ptr++ = *src;
  93.           ++src;
  94.         }
  95.       if (quote)
  96.         {
  97.           ADD (1+bs);
  98.           memset (arg_ptr, '\\', bs);
  99.           arg_ptr += bs;
  100.           *arg_ptr++ = '"';
  101.         }
  102.       ++src;
  103.     }
  104.   ADD (1);
  105.   *arg_ptr++ = 0;
  106.   rc = DosExecPgm (obj, sizeof (obj), exec_flag, arg_buf,
  107.                    (const char *)np->env_off, &res, pgm_name);
  108.   if (arg_buf != NULL)
  109.     free (arg_buf);
  110.   if (rc != 0)
  111.     {
  112.       _sys_set_errno (rc);
  113.       return (-1);
  114.     }
  115.   switch (np->mode & 0xff)
  116.     {
  117.     case P_WAIT:
  118.       return (res.codeResult);
  119.     case P_NOWAIT:
  120.       return (res.codeTerminate);
  121.     case P_OVERLAY:
  122.       while (1)
  123.         DosExit (EXIT_PROCESS, 0);
  124.     default:
  125.       errno = EINVAL;
  126.       return (-1);
  127.     }
  128. }
  129.