home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 4
/
DATAFILE_PDCD4.iso
/
unix
/
unixlib36d
/
src
/
sys
/
c
/
exec
< prev
next >
Wrap
Text File
|
1994-03-08
|
9KB
|
464 lines
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];