簡體   English   中英

子Shell進程雙向重定向到父進程

[英]Child shell process bidirectional redirection to parent process

您好stackoverflow我試圖創建一個程序,該程序執行子外殼程序進程並將其I / O重定向到管道,以便與其父進程進行通信。

我可以通過寫入管道(wpipefd)執行命令,但無法從讀取管道(rpipefd)上的shell進程中獲得響應。

根據Strace到目前為止,我有3個錯誤:首先,read函數正在阻塞程序,因此我將讀取管道的read fd設置為非阻塞( rpipe[0] )。 然后,我的讀取函數出現了EAGAIN錯誤...最后,在使用dup2()之后,在派生進程中關閉了從rpipe( close(rpipefd[0]) )讀取的fd時,我遇到了EPIPE錯誤。

我不明白我做錯了什么。 這是我到目前為止所做的:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#define BUF_SIZE 1024

int main(int argc, char **argv)
{
    int rpipefd[2], wpipefd[2], pid;
    pipe(rpipefd);
    pipe(wpipefd);
    char buffer[BUF_SIZE] = {0};

  int flags = fcntl(rpipefd[0], F_GETFL, 0);
    fcntl(rpipefd[0], F_SETFL, flags | O_NONBLOCK);

    pid = fork();
    if(pid == 0)
    {
        close(rpipefd[0]);
        dup2(rpipefd[1],1);
        dup2(rpipefd[1],2);
        close(wpipefd[1]);
        dup2(wpipefd[0],0);
        close(rpipefd[1]);
        close(wpipefd[0]);
        execl("/bin/sh","/bin/sh",NULL);
    }
    close(wpipefd[0]);
    write(wpipefd[1],"echo helloWorld",strlen("echo helloWorld"));
    close(rpipefd[1]);
    read(rpipefd[0],buffer,BUF_SIZE);       
    //perror("read()");
    printf("%s",buffer);


    exit(0);
}

請幫忙 !

主要問題不在於代碼本身:傳遞給shell的命令不完整,您錯過了最后的'\\ n',因此子進程(您的shell)正在等待命令的其余部分。

非阻塞部分不是一個好主意(或者至少,您應該在管道周圍旋轉以檢索其內容。)

完成命令后,應關閉輸出管道,以便外殼程序在其輸入中獲取文件結尾。

其他說明:您應該等待子進程終止(使用wait(2)),您應該在execl之后退出子進程(與err(3)一起使用以顯示錯誤消息)以處理exec錯誤。 而且,認真地,在字符串文字上調用strlen嗎? 我知道gcc在編譯時會替換它,但是…

這是您的代碼的修改后的版本:

 #include <err.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <sys/wait.h>
 #include <unistd.h>
 #define BUF_SIZE 1024

 int main(int argc, char **argv)
 {
         int rpipefd[2], wpipefd[2], pid;
         pipe(rpipefd);
         pipe(wpipefd);
         char buffer[BUF_SIZE] = {0};

         pid = fork();
         if(pid == 0)
         {
                 close(rpipefd[0]);
                 dup2(rpipefd[1],STDOUT_FILENO);
                 dup2(rpipefd[1],STDERR_FILENO);
                 close(wpipefd[1]);
                 dup2(wpipefd[0],STDIN_FILENO);
                 close(rpipefd[1]);
                 close(wpipefd[0]);
                 execl("/bin/sh","/bin/sh",NULL);
                 err(1, "execl()");
         }
         close(wpipefd[0]);
         close(rpipefd[1]);
         write(wpipefd[1], "echo helloWorld\n", 16);
         close(wpipefd[1]); // we're done, say it to the shell
         int r;
         while ( (r = read(rpipefd[0],buffer,BUF_SIZE)) )
         {
                 if (r == -1)
                 {
                         if (errno == EAGAIN || errno == EINTR) continue;
                         err(1, "read()");
                 }
                 write(STDOUT_FILENO, buffer, r);
         }
         wait(NULL);
         return 0;
 }

暫無
暫無

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

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