Есть ли здесь функция «CreatePipe» и «CreateProcessW» в Linux? - PullRequest
1 голос
/ 18 февраля 2020

Как использовать функции «CreatePipe» и «CreateProcessW» в Linux, когда я компилирую код C ++ в Linux, возникают следующие ошибки: «CreatePipe» не было объявлено в этой области. CreateProcessW не было объявлено в этой области.

1 Ответ

0 голосов
/ 18 февраля 2020

Posix / Linux:

int pipe(int pipefd[2]);

pipefd[0] относится к концу чтения канала.
pipefd[1] относится к концу записи канала.

Linux Speci c:

int pipe2(int pipefd[2], int flags);

Когда дело доходит до CreateProcess, версия Posix / Linux выполняется в несколько шагов.

  • Вызов fork() для создания нового процесса, в котором все еще выполняется одна и та же программа, поэтому теперь два процесса продолжат выполнение одной и той же программы из той же точки, где был вызван fork(). Определение, является ли это родительским процессом или дочерним процессом, выполняется путем проверки возвращаемого значения (идентификатора процесса) из fork().
  • dup файловых дескрипторов, возвращаемых pipe с использованием int dup2(int oldfd, int newfd); для замены stdin и stdout для нового процесса.
  • Выполнение программы в новом процессе с использованием одной из функций exec*.

    // create pipes here
    
    if(pid_t pid = fork(); pid == -1) {
        // fork failed
    
    } else if(pid == 0) { // child process goes here (with a new process id)
        // dup2(...)
        // exec*()
    
    } else {              // parent process goes here
        // do parenting stuff
    }
    

Пример:

#include <unistd.h>
#include <sys/types.h>

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <stdexcept>

struct Pipe {
    Pipe() {
        if(pipe(io)) throw std::runtime_error("pipe failure");
    }
    ~Pipe() {
        close_rd();
        close_wr();
    }
    void close_rd() { closer(io[0]); }
    void close_wr() { closer(io[1]); }
    int rd() { return io[0]; }
    int wr() { return io[1]; }

private:
    void closer(int& fd) {
        if(fd != -1) {
            close(fd);
            fd = -1;
        }
    }
    int io[2];
};

int main() {
    Pipe parent_write, parent_read;

    if(pid_t pid = fork(); pid == -1) {
        // fork failed
        return 1;

    } else if(pid == 0) {   // child process goes here (with a new process id)
        // close file descriptors we don't need:
        parent_write.close_wr();
        parent_read.close_rd();

        // duplicate into the place where stdin/stdout was
        dup2(parent_write.rd(), fileno(stdin));
        dup2(parent_read.wr(), fileno(stdout));

        // execute a program
        execl("/bin/ls", "/bin/ls", nullptr);
        // exec* functions never returns if successful, so if we get here, it failed:
        std::exit(1);

    } else {               // parent process goes here
        std::cout << "child process " << pid << " started\n";
    }

    // close file descriptors we don't need:
    parent_write.close_rd();
    parent_read.close_wr();

    // read data from child process using the file descriptor in parent_read.rd()
    char buf[1024];
    ssize_t rv;
    while((rv = read(parent_read.rd(), buf, 1024))) {
        write(fileno(stdout), buf, static_cast<size_t>(rv));
    }

    // use write(parent_write.wr(), ...) to write to the child.
}
...