home *** CD-ROM | disk | FTP | other *** search
- static char sccs_id[] = "@(#) exec.c 3.0 " __DATE__ " HJR";
-
- /* exec.c (c) Copyright 1990 H.Rogers */
-
- #include <errno.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "fcntl.h"
-
- #include "sys/param.h"
- #include "sys/unix.h"
- #include "sys/syslib.h"
- #include "sys/debug.h"
-
- static int
- __execl (char *name, va_list argp)
- {
- char *argv[MAXCOMMANDLEN >> 2];
- int i;
-
- for (i = 0; i < (MAXCOMMANDLEN >> 2) && (argv[i] = va_arg (argp, char *)); i++);
- if (i >= (MAXCOMMANDLEN >> 2))
- {
- errno = E2BIG;
- return (-1);
- }
- return (execve (name, argv, environ));
- }
-
- int
- execl (char *name,...)
- {
- va_list argp;
- va_start (argp, name);
- return (__execl (name, argp));
- }
-
- int
- execle (char *name,...)
- {
- va_list argp;
- va_start (argp, name);
- return (__execl (name, argp));
- }
-
- int
- execlp (char *name,...)
- {
- va_list argp;
- va_start (argp, name);
- return (__execl (name, argp));
- }
-
- int
- execv (char *name, char **argv)
- {
- return (execve (name, argv, environ));
- }
-
- int
- execvp (char *name, char **argv)
- {
- return (execve (name, argv, environ));
- }
-
-
- #define ushift(p,v) ((p) = __ushift(p,v))
- #define ushift2(p,v,t) ((p) = (t)__ushift((void *)p,v))
-
- static void *
- __ushift (register void *p, register int v)
- {
- register void *q = (char *) p + v;
-
- return (((char *) p >= __base && (char *) p < __break) ? q : p);
- }
-
- #define dshift(p,v) ((p) = __dshift(p,v))
- #define dshift2(p,v,t) ((p) = (t)__dshift((void *)p,v))
-
- static void *
- __dshift (register void *p, register int v)
- {
- register void *q = (char *) p + v;
-
- return (((char *) q >= __base && (char *) q < __break) ? q : p);
- }
-
- os_error *__exerr;
-
- int
- execve (char *name, char **argv, char **envp)
- {
- register struct proc *u = __u;
- register int i, l;
- register char *s1, *s2, *s3;
- register struct env *e;
- void (*__exec) (char *);
- char cli[MAXCOMMANDLEN];
-
- #ifdef DEBUG
- __debug ("execve() (init)");
- #endif
-
- if (!name || !argv || !envp)
- {
- errno = EINVAL;
- return (-1);
- }
-
- if (*name != '*')
- name = __uname (name, 0);
-
- /* check MAXCOMMANDLEN */
-
- #ifdef DEBUG
- os_print ("checking MAXCOMMANDLEN\n\r");
- #endif
-
- l = strlen (name) + 1;
- for (i = 0; argv[i] && l < MAXCOMMANDLEN; l += strlen (argv[i]) + 1, i++);
- if (l >= MAXCOMMANDLEN)
- {
- errno = E2BIG;
- return (-1);
- }
-
- /* shortcut if no parent */
-
- if (!(u->flag & __U_PPROC))
- {
- s2 = cli;
- s3 = name;
- #ifdef DEBUG
- os_print ("Taking a shortcut\n\r");
- #endif
- if (*s3 != '*')
- *s2++ = '/';
- while (*s2++ = *s3++);
- s2[-1] = ' ';
- if (argv[0])
- for (i = 1; s3 = argv[i]; i++)
- {
- while (*s2++ = *s3++);
- s2[-1] = ' ';
- }
- s2[-1] = 0;
- __reset ();
-
- if (strlen (cli) >= MAXPATHLEN) /* We need to use DDE utils for this */
- {
- int r[10];
- char *temp = strchr (cli, ' ');
- #ifdef DEBUG
- os_print ("Shortcut requires DDE\n\r");
- #endif
- if ((temp - cli) >= MAXPATHLEN)
- {
- errno = E2BIG;
- return (-1);
- } /* still too long */
- r[0] = strlen (temp + 1);
- if (os_swi (0x42581, r))
- {
- errno = E2BIG;
- return (-1);
- } /* no DDE utils */
- r[0] = (int) temp + 1;
- os_swi (0x42582, r);
- *temp = '\0';
- #ifdef DEBUG
- os_print ("Shortcut - DDE setup\n\r");
- #endif
- }
-
- os_cli (cli);
- {
- int r[10];
- r[0] = r[1] = r[2] = 0;
- os_swi (0x11, r);
- }
- }
-
- /* check for overlapping argv arrays */
- #ifdef DEBUG
- os_print ("Doing it the long way\n\r");
- #endif
-
- l = argv - u->argv;
- if (l < 0)
- l = -l;
-
- if (l <= i)
- {
- errno = EINVAL;
- return (-1);
- }
-
- /* check free memory */
-
- if (((unsigned int) __base & ~0xff) == 0x8000)
- __exshift = ((char *) __stack - (char *) __break) - 512 - __exlen;
- else
- __exshift = 0;
-
- if (__exshift < MAXCOMMANDLEN)
- {
- errno = ENOMEM;
- return (-1);
- }
-
- /* copy name into u->argb */
-
- s1 = u->argb;
- s2 = cli;
- s3 = name;
- if (*s3 != '*')
- *s2++ = '/';
- while (*s1++ = *s2++ = *s3++);
- s2[-1] = ' ';
-
- /* write cli args, u->argv[] & u->argc */
-
- if (argv[0])
- {
- s3 = argv[0];
- u->argv[0] = s1;
- while (*s1++ = *s3++);
- for (i = 1; s3 = argv[i]; i++)
- {
- u->argv[i] = s1;
- while (*s1++ = *s2++ = *s3++);
- s2[-1] = ' ';
- }
- }
- else
- {
- i = 0;
- *s1 = 0;
- }
-
- u->argv[u->argc = i] = 0;
-
- /* terminate cli */
-
- s2[-1] = 0;
-
- #ifdef DEBUG
- os_print ("cli set up : ");
- os_print (cli);
- os_print ("\n\r");
- #endif
-
- if (strlen (cli) >= MAXPATHLEN) /* We need to use DDE utils for this */
- {
- int r[10];
- char *temp = cli;
- if (*temp == '*')
- temp++;
- while (*temp == ' ')
- temp++; /* command starts star, space - right pain */
-
- temp = strchr (temp, ' ');
- #ifdef DEBUG
- os_print ("long way requires DDE : ");
- os_print (cli);
- os_print ("\n\r");
- #endif
- if ((temp - cli) >= MAXPATHLEN)
- {
- errno = E2BIG;
- return (-1);
- } /* still too long */
- r[0] = strlen (temp + 1);
- if (os_swi (0x42581, r))
- {
- errno = E2BIG;
- return (-1);
- } /* no DDE utils */
- r[0] = (int) temp + 1;
- os_swi (0x42582, r);
- *temp = '\0';
- #ifdef DEBUG
- os_print ("DDE utils set up\n\r");
- #endif
- }
-
- #ifdef DEBUG
- __debug ("execve() (argv)");
- #endif
-
- for (i = 0; i < MAXFD; i++)
- if (u->file[i].oflag & O_EXECCL)
- close (i);
-
- alarm (0); /* just in case */
-
- u->flag &= ~__U_PPROC;
-
- #ifdef DEBUG
- __debug ("execve()");
- #endif
-
- /* deinstall handlers */
-
- e = __Oenv;
- for (i = 0; i < 13; i++)
- __wrenv (i, e->h + i);
-
- /* shift __u pointers if necessary */
-
- if (__exshift)
- {
- register int v = __exshift;
- register struct proc *u = __u;
-
- for (i = 0; i < u->argc; i++)
- ushift (u->argv[i], v);
- ushift (u->argv, v);
- ushift (u->argb, v);
- for (i = 0; i < MAXFD; i++)
- if (u->file[i].dup)
- ushift (u->file[i].dup, v);
- for (i = 0; i < MAXTTY; i++)
- {
- if (u->tty[i].out)
- ushift2 (u->tty[i].out, v, int (*)(int));
- if (u->tty[i].in)
- ushift2 (u->tty[i].in, v, int (*)(void));
- if (u->tty[i].scan)
- ushift2 (u->tty[i].scan, v, int (*)(int));
- if (u->tty[i].init)
- ushift2 (u->tty[i].init, v, int (*)(void));
- if (u->tty[i].flush)
- ushift2 (u->tty[i].flush, v, int (*)(void));
-
- if (u->tty[i].del)
- ushift (u->tty[i].del, v);
- if (u->tty[i].buf)
- ushift (u->tty[i].buf, v);
- if (u->tty[i].ptr)
- ushift (u->tty[i].ptr, v);
- }
- ushift (u->tty, v);
-
- __exec = (void (*)(char *)) ((char *) __break + __exshift);
- }
- else
- __exec = __exptr;
-
- {
- int r[10];
- char *v[1];
-
- v[0] = (char *) __u + __exshift;
- r[0] = (int) "UnixLib$env";
- r[1] = (int) v;
- r[2] = 4;
- r[3] = 0;
- r[4] = 1;
- os_swi (0x24, r);
- }
-
- /* copy up m/code routine */
-
- if (__exshift)
- memcpy ((char *) __exec, (char *) __exptr, __exlen);
-
- /* call it... */
-
- #ifdef DEBUG
- os_print ("Final call : ");
- os_print (cli);
- os_print ("\n\r");
- #endif
-
- (*__exec) (cli); /* HACK ME ?? */
-
- /* never reached */
-
- return (0);
- }
-
- void
- __exret (void)
- {
- register struct env *e;
- int i;
-
- /* shift __u pointers back down */
-
- if (__exshift)
- {
- register int v = -__exshift;
- register struct proc *u = __u;
- register int i;
-
- dshift (u->tty, v);
- for (i = 0; i < MAXTTY; i++)
- {
- if (u->tty[i].out)
- dshift2 (u->tty[i].out, v, int (*)(int));
- if (u->tty[i].in)
- dshift2 (u->tty[i].in, v, int (*)(void));
- if (u->tty[i].scan)
- dshift2 (u->tty[i].scan, v, int (*)(int));
- if (u->tty[i].init)
- dshift2 (u->tty[i].init, v, int (*)(void));
- if (u->tty[i].flush)
- dshift2 (u->tty[i].flush, v, int (*)(void));
-
- if (u->tty[i].del)
- dshift (u->tty[i].del, v);
- if (u->tty[i].buf)
- dshift (u->tty[i].buf, v);
- if (u->tty[i].ptr)
- dshift (u->tty[i].ptr, v);
- }
- for (i = 0; i < MAXFD; i++)
- if (u->file[i].dup)
- dshift (u->file[i].dup, v);
- dshift (u->argb, v);
- dshift (u->argv, v);
- for (i = 0; i < u->argc; i++)
- dshift (u->argv[i], v);
- }
-
- /* reinstall handlers */
-
- e = __Cenv;
- for (i = 0; i < 13; i++)
- __wrenv (i, e->h + i);
-
- {
- int r[10];
-
- r[0] = (int) "UnixLib$env";
- r[1] = r[3] = r[4] = 0;
- r[2] = -1;
- os_swi (0x24, r);
- }
-
- #ifdef DEBUG
- __debug ("__exret()");
- #endif
-
- __u->flag |= __U_PPROC;
-
- if (__exerr)
- {
- __seterr (__exerr);
- i = -1;
- }
- else
- i = __intenv ("Sys$ReturnCode", 0);
-
- if (___vret)
- (*___vret) (i);
- else /* oh fuck... */
- _exit (1);
- }
-