home *** CD-ROM | disk | FTP | other *** search
- /* sys/spawnve.c (emx+gcc) -- Copyright (c) 1992-1993 by Eberhard Mattes */
-
- #include <sys/emx.h>
- #include <stdlib.h>
- #include <string.h>
- #include <process.h>
- #include <errno.h>
- #include <os2emx.h>
- #include "syscalls.h"
-
- #define ADD(n) \
- while (arg_size + n > arg_alloc) \
- { \
- arg_alloc += 512; \
- arg_buf = realloc (arg_buf, arg_alloc); \
- if (arg_buf == NULL) \
- { \
- errno = ENOMEM; \
- return (-1); \
- } \
- arg_ptr = arg_buf + arg_size; \
- }
-
- int __spawnve (struct _new_proc *np)
- {
- ULONG rc;
- ULONG exec_flag;
- RESULTCODES res;
- char obj[40], *arg_ptr, *arg_buf;
- char *pgm_name;
- const char *src;
- size_t arg_size, arg_alloc, len;
- int i, quote, bs;
-
- arg_buf = NULL; arg_alloc = 0; arg_size = 0; arg_ptr = NULL;
- switch (np->mode & 0xff)
- {
- case P_WAIT:
- exec_flag = EXEC_SYNC;
- break;
- case P_NOWAIT:
- exec_flag = EXEC_ASYNCRESULT;
- break;
- case P_OVERLAY:
- exec_flag = EXEC_ASYNC;
- break;
- default:
- errno = EINVAL;
- return (-1);
- }
- pgm_name = alloca (strlen ((const char *)np->fname_off) + 5);
- strcpy (pgm_name, (const char *)np->fname_off);
- _defext (pgm_name, "exe");
- src = (const char *)np->arg_off;
- if (np->arg_count > 0)
- {
- ++src; /* skip flags byte */
- len = strlen (src) + 1;
- ADD (len);
- memcpy (arg_ptr, src, len);
- arg_ptr += len; src += len;
- }
- for (i = 1; i < np->arg_count; ++i)
- {
- if (i > 1)
- {
- ADD (1);
- *arg_ptr++ = ' ';
- }
- ++src; /* skip flags byte */
- quote = (*src == 0 || strpbrk (src, " \t") != NULL);
- if (quote)
- {
- ADD (1);
- *arg_ptr++ = '"';
- }
- bs = 0;
- while (*src != 0)
- {
- if (*src == '"')
- {
- ++bs;
- ADD (bs);
- memset (arg_ptr, '\\', bs);
- bs = 0;
- }
- else if (*src == '\\')
- ++bs;
- else
- bs = 0;
- ADD (1);
- *arg_ptr++ = *src;
- ++src;
- }
- if (quote)
- {
- ADD (1+bs);
- memset (arg_ptr, '\\', bs);
- arg_ptr += bs;
- *arg_ptr++ = '"';
- }
- ++src;
- }
- ADD (1);
- *arg_ptr++ = 0;
- rc = DosExecPgm (obj, sizeof (obj), exec_flag, arg_buf,
- (const char *)np->env_off, &res, pgm_name);
- if (arg_buf != NULL)
- free (arg_buf);
- if (rc != 0)
- {
- _sys_set_errno (rc);
- return (-1);
- }
- switch (np->mode & 0xff)
- {
- case P_WAIT:
- return (res.codeResult);
- case P_NOWAIT:
- return (res.codeTerminate);
- case P_OVERLAY:
- while (1)
- DosExit (EXIT_PROCESS, 0);
- default:
- errno = EINVAL;
- return (-1);
- }
- }
-