Heim > Backend-Entwicklung > C++ > Hauptteil

Wie kann ich Standardeingaben und -ausgaben ordnungsgemäß an einen untergeordneten Prozess unter Linux weiterleiten?

Linda Hamilton
Freigeben: 2024-11-08 19:39:02
Original
225 Leute haben es durchsucht

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

Untergeordnete Prozesse mit Piped-Standardeingabe und -ausgabe unter Linux ausführen

Betrachten Sie die folgende Funktion:

string f(string s) {
    string r = system("foo < s");
    return r;
}
Nach dem Login kopieren

Dies Die Funktion versucht, das Programm „foo“ mit der Zeichenfolge s als Standardeingabe auszuführen und erfasst die Standardausgabe des Programms in der Zeichenfolge r. Dieser Ansatz ist jedoch nicht praktikabel.

Um diese Funktionalität korrekt zu implementieren, ist eine Kombination aus Linux-Systemaufrufen oder POSIX-Funktionen erforderlich:

#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;
}
Nach dem Login kopieren

Diese Funktion createChild richtet eine Pipe zwischen den ein übergeordnete und untergeordnete Prozesse, die die Standardeingabe und -ausgabe des untergeordneten Elements zur und von der Pipe umleiten. Der übergeordnete Prozess kann dann über die Pipe Eingaben an das untergeordnete Element senden und die Ausgabe des untergeordneten Elements aus derselben Pipe lesen.

Das obige ist der detaillierte Inhalt vonWie kann ich Standardeingaben und -ausgaben ordnungsgemäß an einen untergeordneten Prozess unter Linux weiterleiten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage