|
|
1.1 root 1: /* sysdos.c -- DOS version of system.c */
2:
3: /* Author:
4: * Guntram Blohm
5: * Buchenstrasse 19
6: * 7904 Erbach, West Germany
7: * Tel. ++49-7305-6997
8: * sorry - no regular network connection
9: */
10:
11:
12: /* This file is derived from Steve Kirkendall's system.c.
13: *
14: * Entry points are:
15: * system(cmd) - run a single shell command
16: * wildcard(names) - expand wildcard characters in filanames
17: *
18: * This file is for use with DOS and TOS. For OS/2, slight modifications
19: * might be sufficient. For UNIX, use system.c. For Amiga, completely
20: * rewrite this stuff.
21: *
22: * Another system function, filter, is the same on DOS and UNIX and thus
23: * can be found in the original system.c.
24: */
25:
26: #include "config.h"
27: #include "vi.h"
28: extern char **environ;
29:
30:
31: #if MSDOS
32: #include <process.h>
33: extern unsigned char _osmajor;
34: #endif
35: #if TOS
36: #include <osbind.h>
37: #endif
38:
39:
40: #if MSDOS || TOS
41: #include <string.h>
42:
43: /*
44: * Calling command is a bit nasty because of the undocumented yet sometimes
45: * used feature to change the option char to something else than /.
46: * Versions 2.x and 3.x support this, 4.x doesn't.
47: *
48: * For Atari, some shells define a shortcut entry which is faster than
49: * shell -c. Also, Mark Williams uses a special ARGV environment variable
50: * to pass more than 128 chars to a called command.
51: * We try to support all of these features here.
52: */
53:
54: int system(cmd)
55: const char *cmd;
56: {
57: #if MSDOS
58: char *cmdswitch="/c";
59: if (_osmajor<4)
60: cmdswitch[0]=switchar();
61: return spawnle(P_WAIT, o_shell, o_shell, cmdswitch, cmd, (char *)0, environ);
62: #else
63: long ssp;
64: int (*shell)();
65: char line[130];
66: char env[4096], *ep=env;
67: int i;
68:
69: /* does our shell have a shortcut, that we can use? */
70:
71: ssp = Super(0L);
72: shell = *((int (**)())0x4F6);
73: Super(ssp);
74: if (shell)
75: return (*shell)(cmd);
76:
77: /* else we'll have to call a shell ... */
78:
79: for (i=0; environ[i] && strncmp(environ[i], "ARGV=", 5); i++)
80: { strcpy(ep, environ[i]);
81: ep+=strlen(ep)+1;
82: }
83: if (environ[i])
84: {
85: strcpy(ep, environ[i]); ep+=strlen(ep)+1;
86: strcpy(ep, o_shell); ep+=strlen(ep)+1;
87: strcpy(ep, "-c"); ep+=3;
88: strcpy(ep, cmd); ep+=strlen(ep)+1;
89: }
90: *ep='\0';
91: strcpy(line+1, "-c ");
92: strncat(line+1, cmd, 126);
93: line[0]=strlen(line+1);
94: return Pexec(0, o_shell, line, env);
95: #endif
96: }
97:
98: /* This private function opens a pipe from a filter. It is similar to the
99: * system() function above, and to popen(cmd, "r").
100: * sorry - i cant use cmdstate until rpclose, but get it from spawnle.
101: */
102:
103: static int cmdstate;
104: static char output[80];
105:
106: int rpipe(cmd, in)
107: char *cmd; /* the filter command to use */
108: int in; /* the fd to use for stdin */
109: {
110: int fd, old0, old1, old2;
111:
112: /* create the file that will collect the filter's output */
113: strcpy(output, o_directory);
114: if ((fd=strlen(output)) && !strchr("/\\:", output[fd-1]))
115: output[fd++]=SLASH;
116: strcpy(output+fd, SCRATCHIN+3);
117: mktemp(output);
118: close(creat(output, 0666));
119: if ((fd=open(output, O_RDWR))==-1)
120: {
121: unlink(output);
122: return -1;
123: }
124:
125: /* save and redirect stdin, stdout, and stderr */
126: old0=dup(0);
127: old1=dup(1);
128: if (in)
129: {
130: dup2(in, 0);
131: close(in);
132: }
133: dup2(fd, 1);
134:
135: /* call command */
136: cmdstate=system(cmd);
137:
138: /* restore old std... */
139: dup2(old0, 0); close(old0);
140: dup2(old1, 1); close(old1);
141:
142: /* rewind command output */
143: lseek(fd, 0L, 0);
144: return fd;
145: }
146:
147: /* This function closes the pipe opened by rpipe(), and returns 0 for success */
148: int rpclose(fd)
149: int fd;
150: {
151: int status;
152:
153: close(fd);
154: unlink(output);
155: return cmdstate;
156: }
157:
158: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.