Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah saya boleh menyalurkan input dan output standard dengan betul kepada proses kanak-kanak di Linux?

Bagaimanakah saya boleh menyalurkan input dan output standard dengan betul kepada proses kanak-kanak di Linux?

Linda Hamilton
Linda Hamiltonasal
2024-11-08 19:39:02226semak imbas

How can I properly pipe standard input and output to a child process in Linux?

Melaksanakan Proses Kanak-kanak dengan Input dan Output Standard Paip dalam Linux

Pertimbangkan fungsi berikut:

string f(string s) {
    string r = system("foo < s");
    return r;
}

Ini fungsi cuba untuk melaksanakan program "foo" dengan rentetan s sebagai input piawainya, menangkap output piawai program dalam rentetan r. Walau bagaimanapun, pendekatan ini tidak berdaya maju.

Untuk melaksanakan fungsi ini dengan betul, gabungan panggilan sistem Linux atau fungsi POSIX diperlukan:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int createChild(const char *szCommand, char *const aArguments[], char *const aEnvironment[],
               const char *szMessage) {
  int aStdinPipe[2];
  int aStdoutPipe[2];
  int nChild;
  char nChar;

  if (pipe(aStdinPipe) < 0) {
    perror("allocating pipe for child input redirect");
    return -1;
  }
  if (pipe(aStdoutPipe) < 0) {
    close(aStdinPipe[PIPE_READ]);
    close(aStdinPipe[PIPE_WRITE]);
    perror("allocating pipe for child output redirect");
    return -1;
  }

  nChild = fork();
  if (0 == nChild) {
    // child continues here

    // redirect stdin
    if (dup2(aStdinPipe[PIPE_READ], STDIN_FILENO) == -1) {
      exit(errno);
    }

    // redirect stdout
    if (dup2(aStdoutPipe[PIPE_WRITE], STDOUT_FILENO) == -1) {
      exit(errno);
    }

    // redirect stderr
    if (dup2(aStdoutPipe[PIPE_WRITE], STDERR_FILENO) == -1) {
      exit(errno);
    }

    // run child process image
    // (replace this with any `exec*` function you find easier to use)
    execve(szCommand, aArguments, aEnvironment);

    // if we get here at all, an error occurred, but we are in the child
    // process, so just exit
    exit(errno);
  } else if (nChild > 0) {
    // parent continues here

    // close unused file descriptors
    close(aStdinPipe[PIPE_READ]);
    close(aStdoutPipe[PIPE_WRITE]);

    // send message to child (if provided)
    if (NULL != szMessage) {
      write(aStdinPipe[PIPE_WRITE], szMessage, strlen(szMessage));
    }

    // read child's output
    while (read(aStdoutPipe[PIPE_READ], &nChar, 1) == 1) {
      write(STDOUT_FILENO, &nChar, 1);
    }

    // close pipes
    close(aStdinPipe[PIPE_WRITE]);
    close(aStdoutPipe[PIPE_READ]);
  } else {
    // failed to create child
    close(aStdinPipe[PIPE_READ]);
    close(aStdinPipe[PIPE_WRITE]);
    close(aStdoutPipe[PIPE_READ]);
    close(aStdoutPipe[PIPE_WRITE]);
  }
  return nChild;
}

Fungsi createChild ini menyediakan paip antara proses ibu bapa dan anak, mengubah hala input dan output standard kanak-kanak ke dan dari paip. Proses ibu bapa kemudiannya boleh menghantar input kepada kanak-kanak melalui paip dan membaca output kanak-kanak daripada paip yang sama.

Atas ialah kandungan terperinci Bagaimanakah saya boleh menyalurkan input dan output standard dengan betul kepada proses kanak-kanak di Linux?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn