1989-12-18 14:40:54 +00:00
|
|
|
/*
|
|
|
|
* popen - open a pipe
|
|
|
|
*/
|
1994-06-24 14:02:31 +00:00
|
|
|
/* $Id$ */
|
1989-12-18 14:40:54 +00:00
|
|
|
|
2018-06-21 20:33:47 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#if defined(__BSD4_2)
|
1989-12-18 14:40:54 +00:00
|
|
|
union wait {
|
2018-06-21 20:33:47 +00:00
|
|
|
int w_status;
|
1989-12-18 14:40:54 +00:00
|
|
|
};
|
|
|
|
typedef union wait wait_arg;
|
|
|
|
#else
|
|
|
|
typedef int wait_arg;
|
2018-06-21 20:33:47 +00:00
|
|
|
#endif /* __BSD4_2 */
|
|
|
|
#include "../stdio/loc_incl.h"
|
1989-12-18 14:40:54 +00:00
|
|
|
|
1990-01-22 11:44:21 +00:00
|
|
|
int _close(int d);
|
1991-09-18 09:19:40 +00:00
|
|
|
#if defined(__USG)
|
|
|
|
static
|
|
|
|
#endif
|
2018-06-21 20:33:47 +00:00
|
|
|
int
|
|
|
|
_dup2(int oldd, int newd); /* not present in System 5 */
|
|
|
|
int _execl(const char* name, ...);
|
1990-01-22 11:44:21 +00:00
|
|
|
int _fork(void);
|
|
|
|
int _pipe(int fildes[2]);
|
2018-06-21 20:33:47 +00:00
|
|
|
int _wait(wait_arg* status);
|
1989-12-18 14:40:54 +00:00
|
|
|
void _exit(int status);
|
|
|
|
|
1991-09-18 09:19:40 +00:00
|
|
|
static int pids[FOPEN_MAX];
|
1989-12-18 14:40:54 +00:00
|
|
|
|
2018-06-21 20:33:47 +00:00
|
|
|
FILE* popen(const char* command, const char* type)
|
1989-12-18 14:40:54 +00:00
|
|
|
{
|
|
|
|
int piped[2];
|
|
|
|
int Xtype = *type == 'r' ? 0 : *type == 'w' ? 1 : 2;
|
|
|
|
int pid;
|
|
|
|
|
2018-06-21 20:33:47 +00:00
|
|
|
if (Xtype == 2 || _pipe(piped) < 0 || (pid = _fork()) < 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (pid == 0)
|
|
|
|
{
|
1989-12-18 14:40:54 +00:00
|
|
|
/* child */
|
2018-06-21 20:33:47 +00:00
|
|
|
register int* p;
|
1989-12-18 14:40:54 +00:00
|
|
|
|
2018-06-21 20:33:47 +00:00
|
|
|
for (p = pids; p < &pids[FOPEN_MAX]; p++)
|
|
|
|
{
|
|
|
|
if (*p)
|
|
|
|
_close(p - pids);
|
1989-12-18 14:40:54 +00:00
|
|
|
}
|
1990-01-22 11:44:21 +00:00
|
|
|
_close(piped[Xtype]);
|
|
|
|
_dup2(piped[!Xtype], !Xtype);
|
|
|
|
_close(piped[!Xtype]);
|
2018-06-21 20:33:47 +00:00
|
|
|
_execl("/bin/sh", "sh", "-c", command, (char*)0);
|
|
|
|
_exit(127); /* like system() ??? */
|
1989-12-18 14:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pids[piped[Xtype]] = pid;
|
1990-01-22 11:44:21 +00:00
|
|
|
_close(piped[!Xtype]);
|
1989-12-18 14:40:54 +00:00
|
|
|
return fdopen(piped[Xtype], type);
|
|
|
|
}
|
|
|
|
|
2018-06-21 20:33:47 +00:00
|
|
|
#if defined(__BSD4_2)
|
|
|
|
#define ret_val status.w_status
|
1989-12-18 14:40:54 +00:00
|
|
|
#else
|
2018-06-21 20:33:47 +00:00
|
|
|
#define ret_val status
|
1989-12-18 14:40:54 +00:00
|
|
|
#endif
|
|
|
|
|
2018-06-21 20:33:47 +00:00
|
|
|
int pclose(FILE* stream)
|
1989-12-18 14:40:54 +00:00
|
|
|
{
|
|
|
|
int fd = fileno(stream);
|
|
|
|
wait_arg status;
|
|
|
|
int wret;
|
|
|
|
void (*intsave)(int) = signal(SIGINT, SIG_IGN);
|
|
|
|
void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
|
|
|
|
|
|
|
|
fclose(stream);
|
2018-06-21 20:33:47 +00:00
|
|
|
while ((wret = _wait(&status)) != -1)
|
|
|
|
{
|
|
|
|
if (wret == pids[fd])
|
|
|
|
break;
|
1989-12-18 14:40:54 +00:00
|
|
|
}
|
2018-06-21 20:33:47 +00:00
|
|
|
if (wret == -1)
|
|
|
|
ret_val = -1;
|
1989-12-18 14:40:54 +00:00
|
|
|
signal(SIGINT, intsave);
|
|
|
|
signal(SIGQUIT, quitsave);
|
|
|
|
pids[fd] = 0;
|
|
|
|
return ret_val;
|
|
|
|
}
|
|
|
|
|
2018-06-21 20:33:47 +00:00
|
|
|
#if defined(__USG)
|
1990-01-22 11:44:21 +00:00
|
|
|
int _dup(int fildes);
|
|
|
|
|
|
|
|
static int
|
|
|
|
_dup2(int oldd, int newd)
|
1989-12-18 14:40:54 +00:00
|
|
|
{
|
|
|
|
int i = 0, fd, tmp;
|
1991-09-18 09:19:40 +00:00
|
|
|
int fdbuf[FOPEN_MAX];
|
1989-12-18 14:40:54 +00:00
|
|
|
|
|
|
|
/* ignore the error on the close() */
|
2018-06-21 20:33:47 +00:00
|
|
|
tmp = errno;
|
|
|
|
(void)_close(newd);
|
|
|
|
errno = tmp;
|
|
|
|
while ((fd = _dup(oldd)) != newd)
|
|
|
|
{
|
|
|
|
if (fd == -1)
|
|
|
|
break;
|
1989-12-18 14:40:54 +00:00
|
|
|
fdbuf[i++] = fd;
|
|
|
|
}
|
|
|
|
tmp = errno;
|
2018-06-21 20:33:47 +00:00
|
|
|
while (--i >= 0)
|
|
|
|
{
|
1990-01-22 11:44:21 +00:00
|
|
|
_close(fdbuf[i]);
|
1989-12-18 14:40:54 +00:00
|
|
|
}
|
|
|
|
errno = tmp;
|
|
|
|
return -(fd == -1);
|
|
|
|
}
|
2018-06-21 20:33:47 +00:00
|
|
|
#endif /* __USG */
|