Taking over a child process's stdin/stdout

Taking over a child process's stdin/stdout

Post by !**?#! » Wed, 30 Sep 1998 04:00:00



Quote:> ) int main(int argc, char *argv[])
> ) {
> )   int r[2], w[2];

int     pid;

Quote:> )   char buff[200];
> )
> )   pipe(r);
> )   pipe(w);
> )

pid = fork();                   not only if the fork failed
if (pid<0) fork failed;         but also so you know what process
if (pid>0);                     to wait for.

Quote:> )   if (fork())  {
> ) /*************************************************************************/
> ) /* Parent  */
> ) /*************************************************************************/

I never remember which end is which, so I'll assume you've got it right.

        close(w[0]); close(r[1]);

Quote:> ) write( w[PIPE_WRITE], "Hello\n", 6);  /* Send some data  */  read(
> ) r[PIPE_READ], buff, 6 );  /* Check for echo'ed data  */  printf("%.6s",

Warning: this kind of full-duplex setup with blocking reads and writes can
deadlock your program. Proceed with caution.

Quote:> ) buff);  }  else  {
> ) /*************************************************************************/
> ) /* Child  */
> ) /*************************************************************************/
> ) close( r[0]);  /* attatch r[0] to stdout  */  close( STDOUT_FILENO);  dup2(
> ) r[1], STDOUT_FILENO);  close( r[1]);
> )
> )   close( w[1]);  /* attatch w[1] to stdin  */  close( STDIN_FILENO);  dup2(
> ) w[0], STDIN_FILENO);  close( w[0]);
> )
> )  

/*************************************************************************/

Quote:> )  /* Exec awk, to run a program which just echo's back whatever is it
sent */
> ) /*************************************************************************/
> ) execlp("awk", "awk", "{ print $0 }", NULL);  }
> )
> )   return 0;
> ) }

--
They wait apart in waning day,      |meow   I don't use no smilies.

They rest their *, the rest is silence.|   www.geocities.com
Their empty years are ash and clay. | /SoHo/Studios/5079/index.html
I was flamed by Mattison  and all I got was this stupid .signature.
 
 
 

Taking over a child process's stdin/stdout

Post by Andrew Gabri » Wed, 30 Sep 1998 04:00:00




Quote:

>Well, it's only reads that are blocking. In the real code I will use SIGALRM
>to provide a timeout for these.

>However, despite your suggested modifications, the program exhibits the same
>old behaviour.

awk is probably using printf for output, which is buffered.
Certainly, running your program under truss on Solaris shows
awk reads your "Hello\n" in stdio, fxstat's stdout, but never
does a write. Thus it's waiting until it's built up enough
buffered output before writing anything to the pipe.

You're waiting for it's output before giving it any more
input. As predicted by the previous poster, this is a
recipie for a deadlock, which is exactly what you've got.

Quote:>FYI, this occurs on AIX and UnixWare 7.
>In the child process after I have attached the pipes, doing a read on
>STDIN_FILENO has the same effects as an fgets on stdin - they both come from
>the pipe. Doing a write to STDOUT_FILENO goes down the pipe correctly, but
>fprintf's output just seems to disappear.

As above, buffered until it has a large enough chunk of
data to be worth writing. If you are writing the child
process, you can set the output buffering to line buffered
(see setvbuf), but if the child is a precompiled program
which was not written in this way and you can't modify it
(e.g. awk), it's not going to work. (Doing the setvbuf
before the exec won't work either.)

From your original message:

Quote:>Ultimately, I want to have a de* (adb, crash, etc.) running concurrently
>with my program, communicating through unnamed pipes. This would mean that my
>program could issue "od sixt_buf_var" or something similar, and get the
>response.

De*s usually stop the process they attach to whilst
doing things like od sixt_buf_var. That's an even bigger
scope for a deadlock - de* reading from a process
it has stopped :-)

Perhaps you could explain why you want to do this, and
someone might point you in a better direction...

--
Andrew Gabriel
Consultant Software Engineer

 
 
 

Taking over a child process's stdin/stdout

Post by !**?#! » Thu, 01 Oct 1998 04:00:00


Quote:> ) straight away. I imagine I could use the same technique for my program. How
> ) does the shell achieve this?

The shell doesn't. If stdio sees that stdout looks like terminal, it sets
end of line bufferring.

--
They wait apart in waning day,      |meow   I don't use no smilies.

They rest their *, the rest is silence.|   www.geocities.com
Their empty years are ash and clay. | /SoHo/Studios/5079/index.html
I was flamed by Mattison  and all I got was this stupid .signature.

 
 
 

Taking over a child process's stdin/stdout

Post by Barry Margoli » Thu, 01 Oct 1998 04:00:00




>> ) straight away. I imagine I could use the same technique for my program. How
>> ) does the shell achieve this?

>The shell doesn't. If stdio sees that stdout looks like terminal, it sets
>end of line bufferring.

Which leads to the common solution to many problems involving buffering:
use a PTY.  Programs like Expect run the application with its I/O
streams connected to a pty so that it will behave in the normal,
interactive way.  There's a relatively simple program called "pty" that you
should be able to get from Unix source archives; it runs a given command
with its input and/or output connected to a pty, and the output of the pty
command is unbuffered so that the caller can get it easily.

--

GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.

 
 
 

Taking over a child process's stdin/stdout

Post by Andrew Gabri » Thu, 01 Oct 1998 04:00:00




Quote:>> ) straight away. I imagine I could use the same technique for my program. How
>> ) does the shell achieve this?

>The shell doesn't. If stdio sees that stdout looks like terminal, it sets
>end of line bufferring.

If you use pseudo ttys instead of the pipes, you would probably
get line buffering too. I suspect that 'expect' probably does
this if you want some sample source.

--
Andrew Gabriel
Consultant Software Engineer

 
 
 

1. Using separate window child process for stdin/stdout

I have an application which needs to spawn a separate window (xterm,
shelltool, whatever, I don't care) and use that window to pass data in and
out of the parent process. The parent's window is too busy with other status
and info msgs. The parent can poll the stdin pipe with a non-blocking
read().

I know how to set up the pipes and redirect stdin and stdout from a child
process, but I'm stuck on how to do the separate window without getting too
deep into all the terminal IO stuff. Surely there is a straightforward way
to do this?
( I don't need to handle anything other than dumb text entry ).

Any help would be most appreciated.

rev3

2. Linux route tables ... help!

3. redirect stdin/stdout does not for the ftp client child process

4. Sendmail mail archive possible?

5. Access to stdin/stdout of a child process

6. ppp success story ****CORRECTED ******

7. Getting a child and child's child process-id

8. selection service warning starting OW

9. redirect output from child process into parent's stdout

10. avoiding deadlock processing child's stdin/out/err

11. Can a parent process place input as stdin of child process?

12. redirect stdout of child to stdin of parent?