3

I need to execute an external program and access its stdin and stdout alternatively, just like console terminal itself. I have used popen(), but it does not provide a bidirectional pipe. Using pipe() and fork() also does not work interactively, since the write pipe must be closed to access the read pipe.

Please give me some help to come up with it.

3 Answers3

4

You need to open two pipes, one that you connect to stdin of the child process, one that you connect to stdout. You probably also need some way to multiplex input/output in your process.

Another option may be to use a pseudo-terminal, which will give you a two-way communication with the client software that has the pseudoterminal as it's I/O channel - although I'm not quite sure exactly the steps you go through to do this, I'm just suggesting it as I know other programs, such as xterm and ssh uses that method.

The same question has been asked before, and the answer is pretty much what I've described in the first paragraph: popen simultaneous read and write (This answer includes some code that looks OK!)

Community
  • 1
  • 1
Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • But, how do you reconnect stdin or out for an already running process? I do not know a way how to do this. With popen you can only connect to a 'command' either stdin or stdout. – Rick-Rainer Ludwig Feb 01 '13 at 12:29
  • No, you can't do that, but the original question talks about "popen", which opens a process with a pipe. The questioner would have to replicate this with two pipes, which isn't that difficult. Just a call to pipe and dup2(). – Mats Petersson Feb 01 '13 at 12:32
  • Do you have code snippet for that? I had the same question once before and could not solve it. I couldn't connect to an external program with two pipes for stdin and stdout (not to mention stderr ;-)). I think, it is not that easy... – Rick-Rainer Ludwig Feb 01 '13 at 12:44
  • See my latest edit, there's a link to a question asked earlier, which is accepted and has a good number of upvotes, so I presume it's correct. I haven't tried this particular code-snippet, but I've done similarly in the past [not able to post that code, as it was a work project] – Mats Petersson Feb 01 '13 at 12:47
  • I did not try it, but it looks right. Thanks for the hint. This is also the answer of the current question incl. code. – Rick-Rainer Ludwig Feb 01 '13 at 18:10
1

You will have to use OS specific facilities to create separate pipes for both stdout and stdin (and stderr, if you want to). On POSIX platforms you can use dup2() to place appropriate pipe ends to stdout and stdin (and stderr). You will have to restore the original descriptors after you fork(), so do not forget to save them before your place the new ones.

wilx
  • 17,697
  • 6
  • 59
  • 114
0

Pipes do not work that way. You can only use a read or write pipe.

Additionally, standard input and output cannot be the same end point due to direction. It comes from "pipeline work". Someone starts and puts something to stdout which can be used by someone else as stdin and which an again put it ot stdout for a third one...

For bi-directional communication you need to find another way of inter process communication. What it is depends on your implementation.

Rick-Rainer Ludwig
  • 2,371
  • 1
  • 26
  • 42