Home >Backend Development >C++ >How to Execute Child Processes with Piped Stdin and Stdout in Linux?

How to Execute Child Processes with Piped Stdin and Stdout in Linux?

DDD
DDDOriginal
2024-11-19 15:27:03853browse

How to Execute Child Processes with Piped Stdin and Stdout in Linux?

Executing Child Processes with Piped Stdin and Stdout in Linux

In Linux, tasks requiring the execution of child processes with piped standard input (stdin) and standard output (stdout) can be accomplished through various syscalls or POSIX functions. Specifically, for Linux 3.0 and above, the recommended approach involves using pipe(), fork(), execve(), and dup2().

Solution Overview

  1. Create Pipes:

    • Use pipe() to create two pipes: one for stdin (aStdinPipe) and one for stdout (aStdoutPipe).
  2. Fork Process:

    • Use fork() to create a child process.
  3. IO Redirection in Child:

    • In the child process, use dup2() to redirect stdin from aStdinPipe[PIPE_READ] to the child's stdin, and stdout/stderr to aStdoutPipe[PIPE_WRITE].
  4. Close Unused Pipes:

    • Close the unused file descriptors of aStdinPipe[PIPE_READ] and aStdoutPipe[PIPE_WRITE] in the parent process.
  5. Child Execution:

    • Use execve() in the child process to execute the desired command.
  6. IO Communication:

    • In the parent process, write data to aStdinPipe[PIPE_WRITE] to provide input to the child process.
    • Read data from aStdoutPipe[PIPE_READ] to receive the child process's output.

Implementation

The following C code demonstrates this solution:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>

using namespace std;

int main() {
  int aStdinPipe[2], aStdoutPipe[2];
  pid_t childPid;
  char buffer[1024];
  const char* command = "foo";
  string input = "Hello World!";

  // Create pipes
  if (pipe(aStdinPipe) == -1 || pipe(aStdoutPipe) == -1) {
    cerr << "Error creating pipes." << endl;
    return EXIT_FAILURE;
  }

  // Fork child process
  childPid = fork();
  if (childPid == -1) {
    cerr << "Error creating child process." << endl;
    return EXIT_FAILURE;
  }

  // Redirect IO in child process
  if (childPid == 0) {
    // Child process
    if (dup2(aStdinPipe[PIPE_READ], STDIN_FILENO) == -1 ||
        dup2(aStdoutPipe[PIPE_WRITE], STDOUT_FILENO) == -1 ||
        dup2(aStdoutPipe[PIPE_WRITE], STDERR_FILENO) == -1) {
      cerr << "Error redirecting IO in child." << endl;
      return EXIT_FAILURE;
    }

    // Close unused pipes
    close(aStdinPipe[PIPE_READ]);
    close(aStdinPipe[PIPE_WRITE]);
    close(aStdoutPipe[PIPE_WRITE]);

    // Execute command
    execve(command, NULL, NULL);
  }

  // Close unused pipes in parent process
  close(aStdinPipe[PIPE_READ]);
  close(aStdoutPipe[PIPE_WRITE]);

  // Write input to child process
  write(aStdinPipe[PIPE_WRITE], input.c_str(), input.length());

  // Read output from child process
  int numBytesRead = 0;
  while ((numBytesRead = read(aStdoutPipe[PIPE_READ], buffer, sizeof(buffer))) > 0) {
    cout.write(buffer, numBytesRead);
  }

  // Close remaining pipes
  close(aStdinPipe[PIPE_WRITE]);
  close(aStdoutPipe[PIPE_READ]);

  return EXIT_SUCCESS;
}

This code will execute the foo command with the input string input, and the output of foo will be printed to the console.

The above is the detailed content of How to Execute Child Processes with Piped Stdin and Stdout in Linux?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn