DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦b05d88b60⟧ TextFile

    Length: 1462 (0x5b6)
    Types: TextFile
    Notes: UNIX file
    Names: »popen.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦f4b8d8c84⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »libc/stdio/popen.c« 

TextFile

/*
 * Standard I/O library
 * Make streams to or from a process.
 */

#include <stdio.h>
#include <signal.h>

#define	R	0	/* Pipe read descriptor index */
#define	W	1	/* Pipe write descriptor index */

static	int	poppid[_NFILE];

FILE *
popen(command, type)
char *command, *type;
{
	register mode;
	register fd;
	int pd[2];

	if (pipe(pd) < 0)
		return (NULL);
	if (*type == 'w') {
		mode = W;
		fd = pd[W];
	} else {
		mode = R;
		fd = pd[R];
	}
	if ((poppid[fd] = fork()) < 0) {
		close(pd[R]);
		close(pd[W]);
		return (NULL);
	}
	if (poppid[fd] == 0) {		/* Child */
		if (mode == W) {
			close(pd[W]);
			close(fileno(stdin));
			dup(pd[R]);
			close(pd[R]);
		} else {
			close(pd[R]);
			close(fileno(stdout));
			dup(pd[W]);
			close(pd[W]);
		}
		execl("/bin/sh", "sh", "-c", command, NULL);
		exit(1);
	}
	if (mode == W) {
		close(pd[R]);
		return (fdopen(pd[W], "w"));
	} else {
		close(pd[W]);
		return (fdopen(pd[R], "r"));
	}
}

pclose(stream)
FILE *stream;
{
	register fd;
	register pid, wpid;
	int status;
	int (*hupfun)(), (*intfun)(), (*quitfun)();

	fd = fileno(stream);
	pid = poppid[fd];
	poppid[fd] = 0;
	if (pid==0 || fclose(stream)==EOF)
		return (-1);
	hupfun = signal(SIGHUP, SIG_IGN);
	intfun = signal(SIGINT, SIG_IGN);
	quitfun = signal(SIGQUIT, SIG_IGN);
	while ((wpid = wait(&status))!=pid && wpid>=0)
		;
	if (wpid < 0)
		status = -1;
	signal(SIGHUP, hupfun);
	signal(SIGINT, intfun);
	signal(SIGQUIT, quitfun);
	return (status);
}