305 lines
8.5 KiB
C++
305 lines
8.5 KiB
C++
|
|
||
|
|
||
|
/******************* Program chaining functions ********************/
|
||
|
/* Copyright (c) Mix Software 1988 */
|
||
|
|
||
|
system(cmd)
|
||
|
char *cmd;
|
||
|
{
|
||
|
extern int errno;
|
||
|
static char option[] = "/C";
|
||
|
char cmdline[130];
|
||
|
char *comspec;
|
||
|
int _spawn();
|
||
|
int len;
|
||
|
comspec = getenv("COMSPEC=");
|
||
|
if (comspec == NULL) { errno = ENOENT; return -1; }
|
||
|
if ((cmd == NULL) || (*cmd == '\0')) strcpy(cmdline,"\x00\x0d");
|
||
|
else {
|
||
|
len = strlen(cmd);
|
||
|
if (len > 124) {errno = E2BIG; return -1; }
|
||
|
strcpy(cmdline," /C ");
|
||
|
strcat(cmdline,cmd);
|
||
|
cmdline[0] = len+3;
|
||
|
cmdline[len+4] = '\x0d';
|
||
|
}
|
||
|
return _spawn(comspec,cmdline,_copyenv(NULL));
|
||
|
} /* system */
|
||
|
|
||
|
int execl(pathname, arg0)
|
||
|
char *pathname;
|
||
|
char *arg0;
|
||
|
{
|
||
|
return _spawn1(P_OVERLAY,pathname,&arg0,NULL,0);
|
||
|
}
|
||
|
|
||
|
int execle(pathname, arg0)
|
||
|
char *pathname;
|
||
|
char *arg0;
|
||
|
{
|
||
|
char **argptr = &arg0;
|
||
|
while (*argptr != NULL) ++argptr;
|
||
|
return _spawn1(P_OVERLAY,pathname,&arg0,*++argptr,0);
|
||
|
}
|
||
|
|
||
|
int execlp(pathname, arg0)
|
||
|
char *pathname;
|
||
|
char *arg0;
|
||
|
{
|
||
|
return _spawn1(P_OVERLAY,pathname,&arg0,NULL,1);
|
||
|
}
|
||
|
|
||
|
int execlpe(pathname, arg0)
|
||
|
char *pathname;
|
||
|
char *arg0;
|
||
|
{
|
||
|
char **argptr = &arg0;
|
||
|
while (*argptr != NULL) ++argptr;
|
||
|
return _spawn1(P_OVERLAY,pathname,&arg0,*++argptr,1);
|
||
|
}
|
||
|
|
||
|
int execv(pathname, argv)
|
||
|
char *pathname;
|
||
|
char **argv;
|
||
|
{
|
||
|
return _spawn1(P_OVERLAY,pathname,argv,NULL,0);
|
||
|
}
|
||
|
|
||
|
int execve(pathname, argv, envp)
|
||
|
char *pathname;
|
||
|
char *argv[];
|
||
|
char *envp[];
|
||
|
{
|
||
|
return _spawn1(P_OVERLAY,pathname,argv,envp,0);
|
||
|
}
|
||
|
|
||
|
int execvp(pathname, argv)
|
||
|
char *pathname;
|
||
|
char *argv[];
|
||
|
{
|
||
|
return _spawn1(P_OVERLAY,pathname,argv,NULL,1);
|
||
|
}
|
||
|
|
||
|
int execvpe(pathname, argv, envp)
|
||
|
char *pathname;
|
||
|
char *argv[];
|
||
|
char *envp[];
|
||
|
{
|
||
|
return _spawn1(P_OVERLAY,pathname,argv,envp,1);
|
||
|
}
|
||
|
|
||
|
int spawnl(modeflag, pathname, arg0)
|
||
|
int modeflag;
|
||
|
char *pathname;
|
||
|
char *arg0;
|
||
|
{
|
||
|
return _spawn1(modeflag,pathname,&arg0,NULL,0);
|
||
|
}
|
||
|
|
||
|
int spawnle(modeflag, pathname, arg0)
|
||
|
int modeflag;
|
||
|
char *pathname;
|
||
|
char *arg0;
|
||
|
{
|
||
|
char **argptr = &arg0;
|
||
|
while (*argptr != NULL) ++argptr;
|
||
|
return _spawn1(modeflag,pathname,&arg0,*++argptr,0);
|
||
|
}
|
||
|
|
||
|
int spawnlp(modeflag, pathname, arg0)
|
||
|
int modeflag;
|
||
|
char *pathname;
|
||
|
char *arg0;
|
||
|
{
|
||
|
return _spawn1(modeflag,pathname,&arg0,NULL,1);
|
||
|
}
|
||
|
|
||
|
int spawnlpe(modeflag, pathname, arg0)
|
||
|
int modeflag;
|
||
|
char *pathname;
|
||
|
char *arg0;
|
||
|
{
|
||
|
char **argptr = &arg0;
|
||
|
while (*argptr != NULL) ++argptr;
|
||
|
return _spawn1(modeflag,pathname,&arg0,*++argptr,1);
|
||
|
}
|
||
|
|
||
|
int spawnv(modeflag, pathname, argv)
|
||
|
int modeflag;
|
||
|
char *pathname;
|
||
|
char *argv[];
|
||
|
{
|
||
|
return _spawn1(modeflag,pathname,argv,NULL,0);
|
||
|
}
|
||
|
|
||
|
int spawnve(modeflag, pathname, argv, envp)
|
||
|
int modeflag;
|
||
|
char *pathname;
|
||
|
char *argv[];
|
||
|
char *envp[];
|
||
|
{
|
||
|
return _spawn1(modeflag,pathname,argv,envp,0);
|
||
|
}
|
||
|
|
||
|
int spawnvp(modeflag, pathname, argv)
|
||
|
int modeflag;
|
||
|
char *pathname;
|
||
|
char *argv[];
|
||
|
{
|
||
|
return _spawn1(modeflag,pathname,argv,NULL,1);
|
||
|
}
|
||
|
|
||
|
int spawnvpe(modeflag, pathname, argv, envp)
|
||
|
int modeflag;
|
||
|
char *pathname;
|
||
|
char *argv[];
|
||
|
char *envp[];
|
||
|
{
|
||
|
return _spawn1(modeflag,pathname,argv,envp,1);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
spawn and exec driver.
|
||
|
*/
|
||
|
|
||
|
int _spawn1(modeflag, pathname, argv, envp, pathflag)
|
||
|
int modeflag; /* P_WAIT, P_NOWAIT or P_OVERLAY */
|
||
|
char *pathname; /* name of command or exe file */
|
||
|
char *argv[]; /* list of arguments */
|
||
|
char *envp[]; /* pointer to environment */
|
||
|
int pathflag; /* search path environment string */
|
||
|
{
|
||
|
extern int $$ENVALT;
|
||
|
extern unsigned $$ENVIR;
|
||
|
extern char **environ;
|
||
|
extern int errno;
|
||
|
extern int (*_p_chain)();
|
||
|
extern int (*_p_chenv)();
|
||
|
char cmdline[128], path[128];
|
||
|
char *p;
|
||
|
char *pathenv;
|
||
|
int len, handle, status;
|
||
|
if (modeflag == P_NOWAIT) { errno = EINVAL; return -1;}
|
||
|
if (envp == NULL) { /* no environment, use current program's */
|
||
|
if ($$ENVALT != 0) envp = environ;
|
||
|
}
|
||
|
else if (envp == environ) { /* caller has passed current environment */
|
||
|
if ($$ENVALT == 0) envp = NULL;
|
||
|
}
|
||
|
/* envp is null if the original environment will be passed */
|
||
|
if (argv != NULL) { /* make command line from argument list */
|
||
|
if (*argv != NULL) {
|
||
|
*cmdline = ' ';
|
||
|
p = &cmdline[1];
|
||
|
*p = '\0';
|
||
|
len = 1;
|
||
|
while (*++argv != NULL) {
|
||
|
len += strlen(*argv)+1;
|
||
|
if (len > 127) { errno = E2BIG; return -1; }
|
||
|
strcat(cmdline,*argv);
|
||
|
strcat(cmdline," ");
|
||
|
}
|
||
|
cmdline[0] = len-1;
|
||
|
if (len < 127) cmdline[len] = 0x0d;
|
||
|
}
|
||
|
}
|
||
|
/* search for the command or exe file */
|
||
|
if (pathflag != 0) pathenv = getenv("PATH="); else pathenv = 0;
|
||
|
handle = _openfind(pathname,pathenv,".COM;.EXE",0,1,path);
|
||
|
if (handle == -1) { errno = ENOENT; return -1; }
|
||
|
/* execute task */
|
||
|
if (modeflag == P_WAIT) { /* execute and wait for completion */
|
||
|
_sys_ab(0x3e00,handle,&status);
|
||
|
if (envp == NULL) envp = $$ENVIR; else envp = _copyenv(envp);
|
||
|
status = _spawn(path,cmdline,envp);
|
||
|
if (envp != $$ENVIR) free(envp);
|
||
|
return(status);
|
||
|
}
|
||
|
else { /* overlay current program */
|
||
|
if (_p_chain == NULL) {errno = EINVAL; return -1; }
|
||
|
if (envp == NULL) status = (*_p_chain)(handle,cmdline);
|
||
|
else {
|
||
|
envp = _copyenv(envp);
|
||
|
_sys_ab(0x3e00,handle,&status);
|
||
|
status = (*_p_chenv)(path,cmdline,envp);
|
||
|
if (envp != $$ENVIR) free(envp);
|
||
|
}
|
||
|
return status;
|
||
|
}
|
||
|
} /* _spawn1 */
|
||
|
|
||
|
/* Open a file by searching. Name is the basic file name, envir is
|
||
|
a list of possible prefixes and extlist is a list of possible
|
||
|
extensions. Extensions are tried only if the file does not
|
||
|
already have an extension. If the file is succesfully opened,
|
||
|
a file handle is returned, otherwise -1 is returned.
|
||
|
Extensions are tried first, followed by directories.
|
||
|
*/
|
||
|
int _openfind(name, envir, extlist, pathfirst, nonull, newname)
|
||
|
int pathfirst; /* search environment before default directory */
|
||
|
int nonull; /* do not try file without extension */
|
||
|
char *extlist; /* list of extensions to try (if none supplied) */
|
||
|
char *envir; /* list of prefixes to search for file */
|
||
|
char *name; /* base name of file */
|
||
|
char *newname; /* return buffer for name found by the search */
|
||
|
{
|
||
|
int status;
|
||
|
char *p, *q;
|
||
|
char *extptr, *extloc, *final;
|
||
|
char nul = '\0';
|
||
|
int tryit;
|
||
|
strcpy(newname,name);
|
||
|
if (extlist == NULL) extlist = &nul;
|
||
|
else {
|
||
|
p = name+strlen(name);
|
||
|
do { /* search for extension */
|
||
|
if (*p == '.') break; /* found */
|
||
|
if (*p == '\\') break; /* stop on directory name */
|
||
|
if (*p == ':') break; /* stop on disk name */
|
||
|
--p;
|
||
|
} while (p != name);
|
||
|
if (*p == '.') extlist = &nul; /* extension supplied */
|
||
|
}
|
||
|
if (pathfirst == 0) {
|
||
|
if ((nonull == 0) || (extlist == &nul)) {
|
||
|
if (_sys_acd(0x3d00,0,newname,&status) == 0) return status;
|
||
|
}
|
||
|
final = &nul;
|
||
|
}
|
||
|
else final = ";"; /* to try default directory last */
|
||
|
|
||
|
if (envir == NULL) q = &nul; else q = envir;
|
||
|
if (pathfirst == 0) extptr = extlist; else extptr = &nul;
|
||
|
extloc = newname+strlen(newname);
|
||
|
do { /* try all combinations */
|
||
|
if (*extptr != '\0') { /* try next extension */
|
||
|
p = extloc;
|
||
|
while ((*extptr != ';') && (*extptr != '\0')) *p++ = *extptr++;
|
||
|
*p = '\0';
|
||
|
if (*extptr == ';') ++extptr;
|
||
|
tryit = 1;
|
||
|
}
|
||
|
else { /* try next prefix */
|
||
|
p = newname;
|
||
|
while ((*q != ';') && (*q != '\0')) *p++ = *q++;
|
||
|
if (*q == ';') ++q;
|
||
|
if (p != newname) if (*(p-1) != '\\') *p++ = '\\';
|
||
|
*p = '\0';
|
||
|
strcat(p,name);
|
||
|
extptr = extlist;
|
||
|
extloc = newname+strlen(newname);
|
||
|
if ((nonull == 0) || (extlist == &nul)) tryit = 1; else tryit = 0;
|
||
|
}
|
||
|
if (tryit) { /* try to open file with this path */
|
||
|
if (_sys_acd(0x3d00,0,newname,&status) == 0) return status;
|
||
|
}
|
||
|
if (*q == '\0') { /* try default directory (if not tried already) */
|
||
|
q = final;
|
||
|
final = &nul;
|
||
|
}
|
||
|
} while ((*q != '\0') || (*extptr != '\0'));
|
||
|
|
||
|
return -1; /* not found */
|
||
|
} /* _openfind */
|
||
|
|