File:  [Research Unix] / researchv9 / jtools / src / pads / host / popen.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:59 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#include <pads.pri>
#include <CC/signal.h>
SRCFILE("popen.c")
static int popen_pid[_NFILE];

#ifdef BSD
#define SIG_ARG_TYP SIG_TYP
#endif
int pipe(int[2]), wait(int*), vfork(), _exit(int);

FILE *Popen(char *cmd, char *mode)
{
	int parent = (*mode == 'r') ? 0 : 1;
	int child  = (*mode == 'r') ? 1 : 0;
	int p[2];

	if( pipe(p) < 0 ) return NULL;
	int pid = vfork();
	if( pid == 0) {
		dup2(p[child], child);
		setuid(getuid());
		setgid(getgid());
		for( int i = 0; i < _NFILE; ++i )
			if( i != child ) close(i);
		execl("/bin/sh", "sh", "-c", cmd, 0);
		_exit(1);
	}
	if(pid == -1)
		return NULL;
	close(p[child]);
	popen_pid[p[parent]] = pid;
	return(fdopen(p[parent], mode));
}

int Pclose(FILE *ptr)
{
	static SIG_TYP stat[4];
	static int sig[4] = { SIGINT, SIGQUIT, SIGHUP, SIGPIPE };
	int f, r, status, i;

	f = fileno(ptr);
	fclose(ptr);
	for( i = 0; i < 4; ++i )
		stat[i] = signal(sig[i], (SIG_ARG_TYP)SIG_IGN);
	while((r = wait(&status)) != popen_pid[f] && r != -1) {}
	if(r == -1)
		status = -1;
	for( i = 0; i < 4; ++i )
		signal(sig[i], (SIG_ARG_TYP)stat[i]);
	return(status);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.