簡體   English   中英

子進程執行某些系統命令的結果無法通過管道發送給父進程

[英]result of child process's exection of some system command can't send to the father process with pipe

也許這不是一個緊湊的標題,對此我感到非常抱歉:)。 我嘗試通過管道將子進程的stdin / stdout重定向到其父進程。 子進程從父進程輸入執行系統命令,然后將執行結果通過管道返回到父進程。 在這里,我實現了“ cat -n”和“ tr / az / / AZ /”,前者工作正常,但后來沒有返回任何結果。 是什么原因造成的? 謝謝。

#include    <sys/types.h>
#include    <sys/stat.h>
#include    <sys/ipc.h>
#include    <sys/shm.h>
#include    <unistd.h>
#include    <fcntl.h>
#include    <stdio.h>
#include    <stdlib.h>
#include    <errno.h>
#include    <string.h>
#include    <signal.h>
#include    <assert.h>
#include    <sys/sem.h>

#define ERR_EXIT(m) \
     do { \
        perror(m); \
        exit(EXIT_FAILURE); \
    }  while( 0)


int main(int argc, char *argv[])
{

    int chi_pipe[2], par_pipe[2];
    if (pipe(chi_pipe) == -1 || pipe(par_pipe) == -1)
        ERR_EXIT("pipe error");

    /* Set O_NONBLOCK flag for the read end (pfd[0]) of the pipe. */
    if (fcntl(chi_pipe[0], F_SETFL, O_NONBLOCK) == -1) {
        fprintf(stderr, "Call to fcntl failed.\n"); exit(1);
    }

    /* Set O_NONBLOCK flag for the read end (pfd[0]) of the pipe. */
    if (fcntl(chi_pipe[1], F_SETFL, O_NONBLOCK) == -1) {
        fprintf(stderr, "Call to fcntl failed.\n"); exit(1);
    }     


    pid_t pid;
    pid = fork();
    if (pid == -1)
        ERR_EXIT("fork error");


    if (pid == 0)
    {
        close(chi_pipe[0]); // I don't read in channel 1
        close(par_pipe[1]); // I don't write in channel 2
        dup2(chi_pipe[1], STDOUT_FILENO);
        close(STDIN_FILENO);
        dup2(par_pipe[0], STDIN_FILENO);
        execlp("cat", "cat" , "-n", NULL);
        //execlp("tr", "tr" , "/a-z/", "/A-Z/", NULL);
        sleep(10);
        close(chi_pipe[1]);
        close(par_pipe[0]);
        _exit(0);
    }


    close(par_pipe[0]);
    close(chi_pipe[1]);
    while(1) {
        char input[1024];
        memset(input, 0 , 1024);
        fgets(input, 1024 ,stdin);
        write(par_pipe[1], input, strlen(input));
        char buf[3*1024];
        int count = 0;
        while (count <= 0)
            count=read(chi_pipe[0], buf, 1024*3);
        if (count >= 1)
        {
            printf("buf=%s", buf);
            printf("\n");
        }
    }   
    close(par_pipe[1]);
    close(chi_pipe[0]);
    return 0;
}

要點:

  1. 您需要執行非阻塞I / O。 您正在從文件中讀取一行,然后將其寫入管道。 但是不能保證tr會方便地將該行寫回翻譯。 它可能會等待下一行的到來。沒有任何行規。 您需要做的是同時讀取文件,寫入tr (如果管道未滿)和讀取tr (如果字節已准備好)。 或者,更准確地說,根據fd上數據的可用性(讀取)或管道中空間的可用性(寫入)。 否則,您將遇到死鎖問題。 tr之所以不會寫,是因為它寧願先閱讀更多內容,也沒有EOF 您尚未從tr讀取,因為尚未寫入,因此也不會從文件中讀取任何內容。 為此,您想使用select() (或poll() )。

  2. execlp返回的唯一方法是exec失敗。 在那種情況下,您不想exit(0)因為它必然是錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM