2

I have an executable in Linux that can interact with stdin/stdout. I'm trying to write a program in C++ that can interactively call this program, send commands to its stdin, and capture it's stdout.

I've been getting really confused. I don't want to fork my program (do I?). I do want my program to be able to start the "client", send data, get output, send more data, get more output, ..., and close the "client".

P.S. Yes, I'm sure this has been asked before, but I've spent a few hours really scratching my head- probably not using the correct keywords.

3
  • Do you want to write this using low level system calls or can you use libraries? One option is to use libexpect Commented Sep 26, 2016 at 6:04
  • @MarkPlotnick It's a personal project, so anything that makes this easier is the way to go. Commented Sep 27, 2016 at 2:33
  • @MarkPlotnick Actually yes, this works really well! I've switched to using exp_popen() call out of tcl8.6. This opens a process and returns a file handle to it that I can read/write from like any other file. Commented Sep 27, 2016 at 4:14

1 Answer 1

4

The only way to execute another program is via one of the exec() system calls. This is the only way. And, as you know, exec() replaces the executing program with the program specified by exec(). The process that issued the exec() will not exist any more, it's PID is now used by the new program.

It therefore logically follows, that unless you want your program to be replaced by that other executable, your program must fork(), and the child process uses exec() to execute the new executable. This is the traditional way to start a new process, and continue running the original process. A fork() is required for that.

The situation you describe is fairly typical, paint-by-the-numbers situation, that's been done countless of times:

  1. Use pipe() to create two pipes, one for the piped stdin, one for the piped stdout.

  2. Use fork(). The child process dup2()s the read end of the stdin pipe to 0, the write end of the stdout pipe to 1, closes both ends of each of the original pipes, and exec()s the new process.

  3. The parent process closes the read end of the stdin pipe, the write end of the stdout pipe, then proceeds to interact with the child process using the write end of the stdin pipe and the read end of the stdout pipe.

Sign up to request clarification or add additional context in comments.

2 Comments

Very good explanation. You filled in the pieces that were just going over my head in my own research. As an aside, this seems like a horrible interface that would have been replaced and abstracted away a long time ago. Thanks for the help though!
@CircuitGuy Windows does this better, believe it or not. (You call CreateProcess and simply pass it the handles you want the child process to use for stdin and stdout)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.