home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
CMDS
/
elvis1.7.lzh
/
elvis1.7
/
sysdos.c
< prev
next >
Wrap
Text File
|
1993-03-19
|
5KB
|
209 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
* rpipe(cmd, in) - run a shell command with stdin/stdout piped
* rpclose(fd) - close a pipe that was created via rpipe()
* gethome(argv0) - return name of home directory
*
* 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"
#ifndef XDOS
extern char **environ;
#endif
#if MSDOS
#include <process.h>
#ifndef XDOS
extern unsigned char _osmajor;
#endif
#endif
#if TOS
#include <osbind.h>
#endif
#if MSDOS || TOS
#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
char *cmdswitch="/c";
if (_osmajor<4)
cmdswitch[0]=switchar();
return spawnle(P_WAIT, o_shell, o_shell, cmdswitch, cmd, (char *)0, environ);
#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];
int rpipe(cmd, in)
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 (in)
{
dup2(in, 0);
close(in);
}
dup2(fd, 1);
/* call command */
cmdstate=system(cmd);
/* restore old std... */
dup2(old0, 0); close(old0);
dup2(old1, 1); close(old1);
/* rewind command output */
lseek(fd, 0L, 0);
return fd;
}
/* This function closes the pipe opened by rpipe(), and returns 0 for success */
int rpclose(fd)
int fd;
{
int status;
close(fd);
unlink(output);
return cmdstate;
}
/* This function returns the name of the home directory. If there is an
* environment variable named "HOME", then its value is used; otherwise,
* argv[0] is expected to contain the full pathname of the ELVIS.EXE, and
* its directory will be used as the home directory. The first time this
* function is called, you must pass it the value of argv[0] but after that
* you can pass it a NULL pointer.
*
* NOTE: This may alter the argv[0] string.
*/
char *gethome(exe)
char *exe; /* full pathname of the ELVIS.EXE file */
{
static char *home;
/* if this is the first time this func has been called, find home */
if (!home)
{
home = getenv("HOME");
if (!home)
{
home = exe;
exe = strrchr(exe, SLASH);
if (exe)
{
/* Yes, it was a full pathname. Strip off the
* "ELVIS.EXE" part of the name, and use the
* rest as the name of the home directory.
*/
*exe = '\0';
}
else
{
/* Not a full pathname. Use the current
* directory as the home directory.
*/
home = ".";
}
}
}
/* return home */
return home;
}
#endif