Gianluca Guida 4f294c247f Add NBSDLibc Minix specific files.
This patch mainly copies and modifies files existing in
the current libc implementing minix specific functions.

To keep consisten with the NetBSD libc, we remove 
namespace stubs and we use "namespace.h" and weak
links.
2011-02-17 17:11:09 +00:00

129 lines
2.3 KiB
C

/*
* popen - open a pipe
*/
/* $Header$ */
#include <sys/cdefs.h>
#include "namespace.h"
#include <minix/ansi.h>
#ifdef __weak_alias
__weak_alias(popen, _popen)
__weak_alias(pclose, _pclose)
#endif
#include <sys/types.h>
#include <limits.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#if defined(__BSD4_2)
union wait {
int w_status;
};
typedef union wait wait_arg;
#else
typedef int wait_arg;
#endif /* __BSD4_2 */
#ifdef _ANSI
int _close(int d);
int _dup2(int oldd, int newd); /* not present in System 5 */
int _execl(const char *name, const char *_arg, ... );
pid_t _fork(void);
int _pipe(int fildes[2]);
pid_t _wait(wait_arg *status);
void _exit(int status);
#endif
static int pids[OPEN_MAX];
FILE *
popen(command, type)
_CONST char *command;
_CONST char *type;
{
int piped[2];
int Xtype = *type == 'r' ? 0 : *type == 'w' ? 1 : 2;
int pid;
if (Xtype == 2 ||
_pipe(piped) < 0 ||
(pid = _fork()) < 0) return 0;
if (pid == 0) {
/* child */
register int *p;
for (p = pids; p < &pids[OPEN_MAX]; p++) {
if (*p) _close((int)(p - pids));
}
_close(piped[Xtype]);
_dup2(piped[!Xtype], !Xtype);
_close(piped[!Xtype]);
_execl("/bin/sh", "sh", "-c", command, (char *) 0);
_exit(127); /* like system() ??? */
}
pids[piped[Xtype]] = pid;
_close(piped[!Xtype]);
return fdopen(piped[Xtype], type);
}
#if defined(__BSD4_2)
#define ret_val status.w_status
#else
#define ret_val status
#endif
int
pclose(stream)
FILE *stream;
{
int fd = fileno(stream);
wait_arg status;
int wret;
#ifdef _ANSI
void (*intsave)(int) = signal(SIGINT, SIG_IGN);
void (*quitsave)(int) = signal(SIGQUIT, SIG_IGN);
#else
void (*intsave)() = signal(SIGINT, SIG_IGN);
void (*quitsave)() = signal(SIGQUIT, SIG_IGN);
#endif
fclose(stream);
while ((wret = _wait(&status)) != -1) {
if (wret == pids[fd]) break;
}
if (wret == -1) ret_val = -1;
signal(SIGINT, intsave);
signal(SIGQUIT, quitsave);
pids[fd] = 0;
return ret_val;
}
#if defined(__USG)
int _dup(int fildes);
static int
_dup2(oldd, newd)
int oldd, newd;
{
int i = 0, fd, tmp;
int fdbuf[_NFILES];
/* ignore the error on the close() */
tmp = errno; (void) _close(newd); errno = tmp;
while ((fd = _dup(oldd)) != newd) {
if (fd == -1) break;
fdbuf[i++] = fd;
}
tmp = errno;
while (--i >= 0) {
_close(fdbuf[i]);
}
errno = tmp;
return -(fd == -1);
}
#endif /* __USG */