1 /* added real/protect mode branch at runtime and real mode version
2 * names changed for perl
7 Several people in the past have asked about having Unix-like pipe
8 calls in OS/2. The following source file, adapted from 4.3 BSD Unix,
9 uses a #define to give you a pipe(2) call, and contains function
10 definitions for popen(3) and pclose(3). Anyone with problems should
11 send mail to me; they seem to work fine.
15 ----------------------------------cut-here------------------------------------
19 * The following code segment is derived from BSD 4.3 Unix. See
20 * copyright below. Any bugs, questions, improvements, or problems
21 * should be sent to Mark Towfigh (towfiq@interlan.interlan.com).
27 * Copyright (c) 1980 Regents of the University of California.
28 * All rights reserved. The Berkeley software License Agreement
29 * specifies the terms and conditions for redistribution.
43 static FILE *dos_popen(const char *cmd, const char *flags);
44 static int dos_pclose(FILE *pipe);
47 * emulate Unix pipe(2) call
50 #define tst(a,b) (*mode == 'r'? (b) : (a))
54 static int popen_pid[20];
56 FILE *mypopen(char *cmd, char *mode)
59 register myside, hisside, save_stream;
60 char *shell = getenv("COMPSPEC");
63 shell = "C:\\OS2\\CMD.EXE";
65 if ( _osmode == DOS_MODE )
66 return dos_popen(cmd, mode);
68 if (DosMakePipe((PHFILE) &p[0], (PHFILE) &p[1], 4096) < 0)
71 myside = tst(p[WRITEH], p[READH]);
72 hisside = tst(p[READH], p[WRITEH]);
74 /* set up file descriptors for remote function */
75 save_stream = dup(tst(0, 1)); /* don't lose stdin/out! */
76 if (dup2(hisside, tst(0, 1)) < 0)
84 * make sure that we can close our side of the pipe, by
85 * preventing it from being inherited!
88 /* set no-inheritance flag */
89 DosSetFHandState(myside, OPEN_FLAGS_NOINHERIT);
91 /* execute the command: it will inherit our other file descriptors */
92 popen_pid[myside] = spawnlp(P_NOWAIT, shell, shell, "/C", cmd, NULL);
94 /* now restore our previous file descriptors */
95 if (dup2(save_stream, tst(0, 1)) < 0) /* retrieve stdin/out */
102 return fdopen(myside, mode); /* return a FILE pointer */
105 int mypclose(FILE *ptr)
110 if ( _osmode == DOS_MODE )
111 return dos_pclose(ptr);
116 /* wait for process to terminate */
117 cwait(&status, popen_pid[f], WAIT_GRANDCHILD);
123 int pipe(int *filedes)
127 if ( res = DosMakePipe((PHFILE) &filedes[0], (PHFILE) &filedes[1], 4096) )
130 DosSetFHandState(filedes[0], OPEN_FLAGS_NOINHERIT);
131 DosSetFHandState(filedes[1], OPEN_FLAGS_NOINHERIT);
136 /* this is the MS-DOS version */
138 typedef enum { unopened = 0, reading, writing } pipemode;
148 static FILE *dos_popen(const char *command, const char *mode)
158 if(strchr(mode, 'r') != NULL)
160 else if(strchr(mode, 'w') != NULL)
166 ** get a name to use.
168 strcpy(name, "piXXXXXX");
172 ** If we're reading, just call system to get a file filled with
175 if(curmode == reading)
178 sprintf(cmd,"%s > %s", command, name);
181 if((current = fopen(name, mode)) == NULL)
186 if((current = fopen(name, mode)) == NULL)
190 cur = fileno(current);
191 pipes[cur].name = strdup(name);
192 pipes[cur].command = strdup(command);
193 pipes[cur].pmode = curmode;
198 static int dos_pclose(FILE * current)
200 int cur = fileno(current), rval;
204 ** check for an open file.
206 if(pipes[cur].pmode == unopened)
209 if(pipes[cur].pmode == reading)
212 ** input pipes are just files we're done with.
214 rval = fclose(current);
215 unlink(pipes[cur].name);
220 ** output pipes are temporary files we have
221 ** to cram down the throats of programs.
224 sprintf(command,"%s < %s", pipes[cur].command, pipes[cur].name);
225 rval = system(command);
226 unlink(pipes[cur].name);
230 ** clean up current pipe.
232 free(pipes[cur].name);
233 free(pipes[cur].command);
234 pipes[cur].pmode = unopened;