首页  >  文章  >  后端开发  >  如何在 C 中使用管道标准 I/O 执行子进程?

如何在 C 中使用管道标准 I/O 执行子进程?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-11-10 14:08:02626浏览

How to Execute a Child Process with Piped Standard I/O in C  ?

通过管道将标准 I/O 参数传递给子进程

目标是创建一个执行子进程的 C 函数 (" foo") 将提供的字符串作为标准输入 ("s") 并以字符串形式返回子级的标准输出

系统调用和 POSIX 函数

此任务需要以下系统调用和 POSIX 函数:

  • pipe() :创建一个管道用于父子进程之间的通信。
  • fork():创建一个新的子进程process.
  • dup2():将一个文件描述符复制到另一个描述符。
  • execve():在当前进程中执行一个新的程序映像。
  • write():将数据写入文件描述符。
  • read():从文件读取数据

函数实现

下面的函数按照以下步骤使用管道标准 I/O 执行子进程:

  1. 创建两个管道,一个用于标准输入,一个用于标准输出。
  2. 分叉一个新的子管道
  3. 子进程中:

    • 将其标准输入重定向到输入管道的读取端。
    • 重定向其标准输出和标准输出管道的写入端发生错误。
    • 关闭从继承的所有未使用的文件描述符父进程。
    • 使用 execve() 执行子程序(“foo”)。
  4. 在父进程中:

    • 关闭管道未使用的一端。
    • 将输入字符串写入输入的写入端管道。
    • 从输出管道的读取端读取并存储子进程的标准输出。
    • 使用 fork() 等待子进程完成。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#define PIPE_READ 0
#define PIPE_WRITE 1

string f(string s) {
  int inputPipe[2];
  int outputPipe[2];
  pid_t childPid;
  char c;
  string result;

  if (pipe(inputPipe) < 0 || pipe(outputPipe) < 0) {
    perror("Error creating pipes");
    return "";
  }

  if ((childPid = fork()) == -1) {
    perror("Error creating child process");
    return "";
  } else if (childPid == 0) {  // Child process
    // Redirect standard input
    if (dup2(inputPipe[PIPE_READ], STDIN_FILENO) < 0) {
      perror("Error redirecting standard input");
      exit(errno);
    }

    // Redirect standard output and standard error
    if (dup2(outputPipe[PIPE_WRITE], STDOUT_FILENO) < 0) {
      perror("Error redirecting standard output");
      exit(errno);
    }
    if (dup2(outputPipe[PIPE_WRITE], STDERR_FILENO) < 0) {
      perror("Error redirecting standard error");
      exit(errno);
    }

    // Close unused pipes
    close(inputPipe[PIPE_READ]);
    close(inputPipe[PIPE_WRITE]);
    close(outputPipe[PIPE_READ]);

    // Execute child process
    execl("/bin/sh", "sh", "-c", s.c_str(), NULL);
    perror("Error executing child process");
    exit(errno);
  } else {  // Parent process
    // Close unused pipes
    close(inputPipe[PIPE_READ]);
    close(outputPipe[PIPE_WRITE]);

    // Write input string to child's standard input
    write(inputPipe[PIPE_WRITE], s.c_str(), s.size());

    // Read output from child's standard output
    while (read(outputPipe[PIPE_READ], &c, 1) > 0) {
      result += c;
    }

    // Close pipes
    close(inputPipe[PIPE_WRITE]);
    close(outputPipe[PIPE_READ]);

    // Wait for child to finish
    waitpid(childPid, NULL, 0);
  }

  return result;
}

以上是如何在 C 中使用管道标准 I/O 执行子进程?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn