/* wye.c, written by Michael Constant (mconst@csua.berkeley.edu) and placed
 * in the public domain.  $Id: wye.c,v 1.1 1999-05-03 10:04:59-07 mconst $ */

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/errno.h>
#include <sys/stat.h>

#define TEMPMASK "/tmp/wye.XXXXXX"	/* the name of our tempfile */
#define TIMEOUT 3600			/* time we wait for the fifo to open */

void cleanup(int sig);

char tempfile[]=TEMPMASK;

int main()
{
	int ch;
	FILE *fp;

	/* create the fifo.  if we get EEXIST, then someone else created a
	 * file with our intended name right before we did; we should pick
	 * a new name and try again.  see the source to mkstemp(3). */
	while (mkfifo(mkstemp(tempfile), 0600) == -1) {
		if (errno != EEXIST) {
			perror("wye: couldn't create fifo");
			exit(1);
		}
		strcpy(tempfile, TEMPMASK);
	}

	/* remove our tempfile if we die */
	signal(SIGHUP, cleanup);
	signal(SIGINT, cleanup);
	signal(SIGTERM, cleanup);
	signal(SIGALRM, cleanup);

	/* fork a child to do the work */
	switch (fork()) {
	case -1:
		perror("wye: couldn't fork");
		exit(1);

	case 0:
		fclose(stdout);		/* this is necessary for `cmd | wye` */
		alarm(TIMEOUT);		/* this is if the fifo never opens */

		/* this will block until someone else opens the fifo */
		if ((fp = fopen(tempfile, "w")) == NULL) {
			perror("wye: couldn't open fifo");
			exit(1);	/* not as if anyone cares */
		}

		alarm(0);		/* cancel the alarm */
		unlink(tempfile);	/* so it disappears when we're done */
		while ((ch = getchar()) != EOF) putc(ch, fp);
		exit(0);
	}

	/* output the name of the fifo */
	printf("%s\n", tempfile);
	exit(0);
}

void cleanup(int sig)
{
	unlink(tempfile);
	exit(2);
}
