Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 09 Sep 1998 21:08:08 +0000
From:      Mark Ovens <marko@uk.radan.com>
To:        questions@FreeBSD.ORG, freebsd-users@freebsd-uk.eu.org
Subject:   Help needed with fork(), pipe() & dup2()
Message-ID:  <35F6EE38.7DC97F21@uk.radan.com>

next in thread | raw e-mail | index | archive | help
Hi,

I'm trying to make a native FreeBSD binary of a Linux program. The Linux
binary works fine under emulation and I've got most of the thing working
as a native FreeBSD app but there's one thing that's really giving me a
headache.

Below is the code. As you will see, it creates a pipe, forks the
process,
calls dup2() to read/write stdin/stdout, the child calls execvp to run
file(1), "files" being a NULL terminated list of filenames. The parent
reads from the pipe to process the output from file(1).

This works fine the first time the function is called, but on the second
& subsequent calls it never reads anything from the pipe, although
sticking
a printf() immediately before the while(gets... does produce output so
the
prog is getting that far. Since I only get the warning "This program
uses
gets() which is unsafe" the first time I'm assuming that 'gets(line)'
returns NULL immediately the second time the function is called.

Can anyone suggest why this should work under Linux but not as native 
FreeBSD?. Note that the code has been trimmed down and only shows the
overall structure. The return from pipe(), dup2() etc. _is_ tested for
errors and handled accordingly.


void foo()
	{
	char   line [MAX_LINE];
	int    fd [2];
	pid_t  pid;

	pipe(fd);
	if ((pid = fork ()) < 0)
		error_message();
	else
		if (pid > 0)
			{  /* parent */
			close (fd [1]);
			if (fd [0] != STDIN_FILENO)
				{
				dup2(fd [0], STDIN_FILENO)
				close (fd [0]);
				}
					/* read file names from pipe */
			while (gets (line) != NULL)
				 {
					.
					.
				code to process "line" here
					.
					.
				 }

			close (fd [0]);

			}  /* parent */
		else
			{  /* child */
			close (fd [0]);
			if (fd [1] != STDOUT_FILENO)
				{
				dup2(fd [1], STDOUT_FILENO)
				close (fd [1]);
				}
			if (execvp ("file", files) < 0)
				error_message ();
			close (fd [1]);
			}  /* child */
	}


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?35F6EE38.7DC97F21>