dos_compilers/Mix Power C v1/CHAIN.C
2024-07-01 15:26:34 -07:00

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 */