home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 2
/
crawlyvol2.bin
/
apps
/
text_ed
/
elv16b2
/
st
/
sysdos.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-13
|
5KB
|
233 lines
/* sysdos.c -- DOS version of system.c */
/* Author:
* Guntram Blohm
* Buchenstrasse 19
* 7904 Erbach, West Germany
* Tel. ++49-7305-6997
* sorry - no regular network connection
*/
/* This file is derived from Steve Kirkendall's system.c.
*
* Entry points are:
* system(cmd) - run a single shell command
* wildcard(names) - expand wildcard characters in filanames
*
* This file is for use with DOS and TOS. For OS/2, slight modifications
* might be sufficient. For UNIX, use system.c. For Amiga, completely
* rewrite this stuff.
*
* Another system function, filter, is the same on DOS and UNIX and thus
* can be found in the original system.c.
*/
#include "config.h"
#include "vi.h"
extern char **environ;
#if MSDOS || MINT
#include <process.h>
# if MSDOS
extern unsigned char _osmajor;
# endif
#endif
#if TOS || MINT
#include <osbind.h>
#endif
#if MINT
#include <stdio.h>
#endif
#if MSDOS || TOS || MINT
#include <string.h>
/*
* Calling command is a bit nasty because of the undocumented yet sometimes
* used feature to change the option char to something else than /.
* Versions 2.x and 3.x support this, 4.x doesn't.
*
* For Atari, some shells define a shortcut entry which is faster than
* shell -c. Also, Mark Williams uses a special ARGV environment variable
* to pass more than 128 chars to a called command.
* We try to support all of these features here.
*/
int system(cmd)
const char *cmd;
{
#if MSDOS || MINT
# if MINT
static char *extensions[] = { "ttp", "prg", "tos", NULL };
extern char *findfile (char *, char *, char **);
extern char *getenv();
char **argv = 0, *cmdcopy = 0, **argp, *path, *p;
int ret;
size_t clen;
static char cmdpath[FILENAME_MAX];
long ssp;
int (*shell)();
if (cmd == o_shell)
return spawnlp(P_WAIT, o_shell, o_shell, (char *)0);
if (!getenv("NO_SHELLP")) {
ssp = Super(0L);
shell = *((int (**)())0x4F6);
(void) Super(ssp);
if (shell)
return (*shell)(cmd);
}
/* see if cmd is simple enough so that we don't need a shell */
if ((path = getenv("PATH")) && (clen = strlen(cmd)) &&
!strpbrk(cmd, "'\"`><;$~[*?&|(){}") &&
(argv = (char **) malloc((clen/2+2) * sizeof(char *))) &&
(cmdcopy = strdup(cmd)) &&
(p = findfile(strtok(cmdcopy, " \t"), path, extensions))) {
argp = argv;
*argp++ = strcpy(cmdpath, p);
while (*argp++ = strtok((char *) NULL, " \t"))
;
errno = 0;
ret = spawnv(P_WAIT, p, argv);
free(argv);
free(cmdcopy);
if (ret != -1 || errno != ENOEXEC)
return ret;
}
if (argv)
free(argv);
if (cmdcopy)
free(cmdcopy);
return spawnlp(P_WAIT, o_shell, o_shell, "-c", cmd, (char *)0);
# else
char *cmdswitch="/c";
if (_osmajor<4)
cmdswitch[0]=switchar();
return spawnle(P_WAIT, o_shell, o_shell, cmdswitch, cmd, (char *)0, environ);
# endif
#else
long ssp;
int (*shell)();
char line[130];
char env[4096], *ep=env;
int i;
/* does our shell have a shortcut, that we can use? */
ssp = Super(0L);
shell = *((int (**)())0x4F6);
Super(ssp);
if (shell)
return (*shell)(cmd);
/* else we'll have to call a shell ... */
for (i=0; environ[i] && strncmp(environ[i], "ARGV=", 5); i++)
{ strcpy(ep, environ[i]);
ep+=strlen(ep)+1;
}
if (environ[i])
{
strcpy(ep, environ[i]); ep+=strlen(ep)+1;
strcpy(ep, o_shell); ep+=strlen(ep)+1;
strcpy(ep, "-c"); ep+=3;
strcpy(ep, cmd); ep+=strlen(ep)+1;
}
*ep='\0';
strcpy(line+1, "-c ");
strncat(line+1, cmd, 126);
line[0]=strlen(line+1);
return Pexec(0, o_shell, line, env);
#endif
}
/* This private function opens a pipe from a filter. It is similar to the
* system() function above, and to popen(cmd, "r").
* sorry - i cant use cmdstate until rpclose, but get it from spawnle.
*/
static int cmdstate;
static char output[80];
#if MINT
/* MiNT uses real pipes if it can... (wich means unless running vanilla TOS.) */
int trpipe(cmd, in)
#else
int rpipe(cmd, in)
#endif
char *cmd; /* the filter command to use */
int in; /* the fd to use for stdin */
{
int fd, old0, old1, old2;
/* create the file that will collect the filter's output */
strcpy(output, o_directory);
if ((fd=strlen(output)) && !strchr("/\\:", output[fd-1]))
output[fd++]=SLASH;
strcpy(output+fd, SCRATCHIN+3);
mktemp(output);
close(creat(output, 0666));
if ((fd=open(output, O_RDWR))==-1)
{
unlink(output);
return -1;
}
/* save and redirect stdin, stdout, and stderr */
old0=dup(0);
old1=dup(1);
#if MINT
/* ... and stderr :-) */
old2=dup(2);
#endif
if (in)
{
dup2(in, 0);
close(in);
}
dup2(fd, 1);
#if MINT
dup2(fd, 2);
#endif
/* call command */
cmdstate=system(cmd);
/* restore old std... */
dup2(old0, 0); close(old0);
dup2(old1, 1); close(old1);
#if MINT
dup2(old2, 2); close(old2);
#endif
/* rewind command output */
#if TOS || MINT
/* GEMDOS redirection bugs department... */
close(fd);
fd=open(output, O_RDWR);
#else
lseek(fd, 0L, 0);
#endif
return fd;
}
/* This function closes the pipe opened by rpipe(), and returns 0 for success */
#if MINT
int trpclose(fd)
#else
int rpclose(fd)
#endif
int fd;
{
close(fd);
unlink(output);
return cmdstate;
}
#endif