Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

pipe,fork,exec

4 views
Skip to first unread message

Mike - EMAIL IGNORED

unread,
May 21, 2004, 9:39:18 PM5/21/04
to
Using Redhat 9, what is the best way to do it?

Roughly speaking, I got this to work:
{
pipe(); // created 3 & 4
int pid = fork();
if (pid == 0)
{
system("ifconfig 1>&4");
echo theEnd 1>&4; // no eof eas delivered
// execl(/bin/bash,"-c","ifconfig"); // could not get this to send to 4
exit(0); // would not be needed with an exec
}
else
{
char buf; // If no read a line, why a larger buffer?
while(read(3,&buf,1) > 0) // could not figure out how to read a line
{
construct lines, parse, ....
if (a line contains "theEnd") // never got eof
break;
}
waitpid(pid);
close(3);
close(4);
}
}

popen() was rejected because of potential problems between
FILE and C++ I/O.

There must be a better way. Advice and possible reference
to a tutorial or example would be much appreciated.

Thanks,
Mike.

Kasper Dupont

unread,
May 22, 2004, 3:35:59 AM5/22/04
to
Mike - EMAIL IGNORED wrote:
>
> Using Redhat 9, what is the best way to do it?
>
> Roughly speaking, I got this to work:
> {
> pipe(); // created 3 & 4

Here is obviously a bug. Had you included the right
header file <unistd.h> you should have been given a
warning about it. pipe takes an array of two integers
as argument used to return the filedescriptors see
man 2 pipe

Didn't I post this example a few days ago?
int pipefd[2];
...
if (pipe(pipefd)) {
perror("pipe");
exit(EXIT_FAILURE);
}

> int pid = fork();

Delarations after statements is not ANSI C, but
AFAIK it is valid according to C99. Anyway, you
made a few slightly worse mistakes. The right
type would be pid_t not int. And you didn't check
for errors.

> if (pid == 0)
> {
> system("ifconfig 1>&4");
> echo theEnd 1>&4; // no eof eas delivered

This is not C syntax.

> // execl(/bin/bash,"-c","ifconfig"); // could not get this to send to 4

Before execl you would want to setup the
filedescriptors. Like this:

close(pipefd[0]); /* Close the read end, we don't need it */
dup2(pipefd[1],1); /* Put the write end where we need it */
close(pipefd[1]); /* And close the unneeded fd for this end of the pipe */

> exit(0); // would not be needed with an exec
> }
> else
> {
> char buf; // If no read a line, why a larger buffer?
> while(read(3,&buf,1) > 0) // could not figure out how to read a line

You can't read a line from a file descriptor.
You can say how many chars you want, but if
there were a newline in the midle, you would
read past the newline. That is actually a
problem sometimes.

Anyway, you could use stdio which will buffer
the characters and allow you to do fancy stuff.
See fdopen(3).

There is another bug. You keep the write end of
the pipe open. So you will never get an end of
file. Close the write end to avoid deadlocking.

> {
> construct lines, parse, ....
> if (a line contains "theEnd") // never got eof
> break;
> }
> waitpid(pid);

This is wrong. waitpid takes three arguments.

> close(3);
> close(4);

Those filedescriptors are wrong.

> }
> }
>
> popen() was rejected because of potential problems between
> FILE and C++ I/O.

There shouldn't be any problems. And popen is the
obvious choice here.

>
> There must be a better way.

popen is that better way.

> Advice and possible reference
> to a tutorial or example would be much appreciated.

There is some example code here, that might help you
http://www.daimi.au.dk/~kasperd/pshell/

--
Kasper Dupont -- der bruger for meget tid paa usenet.
For sending spam use ab...@mk.lir.dk and kas...@mk.lir.dk
I'd rather be a hammer than a nail.

0 new messages