【问题标题】:Creating a pipe with dup2使用 dup2 创建管道
【发布时间】:2017-05-14 09:36:22
【问题描述】:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void) {
    int pfd1[2];
    int pfd2[2];
    pid_t pid1, pid2, pid3;
    if(pipe(pfd1)==-1) {
        perror("Creazione pipe");
        exit(EXIT_FAILURE);
        }
    if(pipe(pfd2)==-1) {
        perror("Creazione pipe");
        exit(EXIT_FAILURE);
        }
    printf("Sono il padre\n");
    switch(pid1=fork()) {
        printf("%d\n", pid1);
        case -1: {
            perror("Creazione figlio 1");
            exit(EXIT_FAILURE);
            }
        case 0: { //figlio 1
            printf("Sono il figlio 1\n");
            if(dup2(pfd1[1],1)==-1) { //redirige lo stdout sul descrittore scrittura
                perror("Prima redirezione");
                exit(EXIT_FAILURE);
                }
            close(pfd1[0]);
            close(pfd1[1]); //lo chiudo perchè sto redirigendo lo stdout
            close(pfd2[0]);
            close(pfd2[1]);
            execlp("ps", "ps", "-A", "-ostat,pid", (char*) NULL);
            }
        }
    waitpid(pid1,NULL,0);
    switch(pid2=fork()) {
        case -1: {
            perror("Creazione figlio 2");
            exit(EXIT_FAILURE);
            }
        case 0: { //figlio 2
            printf("Sono il figlio 2\n");
            if(dup2(pfd1[0],0)==-1) { //redirige lo stdin sul descrittore lettura
                perror("Seconda redirezione");
                exit(EXIT_FAILURE);
                }
            printf("Prima redirezione figlio 2\n");
            if(dup2(pfd2[1],1)==-1) {
                perror("Terza redirezione");
                exit(EXIT_FAILURE);
                }
            close(pfd1[1]);
            close(pfd1[0]);
            close(pfd2[0]);
            close(pfd2[1]);
            execlp("grep", "grep", "-e", "[zZ]", (char*) NULL);
            }
    waitpid(pid2, NULL,0);
    switch(pid3=fork()) {
        case -1: {
            perror("Creazione terzo figlio");
            exit(EXIT_FAILURE);
            }
        case 0: { //figlio 3
            printf("Sono il figlio 3\n");
            if(dup2(pfd2[0],0)==-1) {
                perror("Quarta redirezione");
                exit(EXIT_FAILURE);
                }
            close(pfd1[0]);
            close(pfd1[1]);
            close(pfd2[0]);
            close(pfd2[1]);
            execlp("awk", "awk", "'{print $2}'", (char*) NULL);
            }
        }
    /*padre*/
    //waitpid(pid1, NULL, 0);
    //waitpid(pid2, NULL, 0);
    waitpid(pid3, NULL, 0);
    close(pfd2[0]);
    close(pfd2[1]);
    close(pfd1[0]);
    close(pfd1[1]);
    return 0;
    }

}

你好, 我正在尝试使用系统调用 dup2 创建一个 shell bash 命令管道。 我期望的输出应该和

一样
bash $> ps -A -ostat,pid | grep -e [zZ] | awk '{print $2}'

我所做的是分叉 3 个孩子并让他们通过两个管道进行通信。每个孩子执行命令的一部分。 问题是我的程序卡在了第二个孩子身上,显然它甚至无法执行 exec。 我确定我的代码存在一些问题,但由于这是我第一次尝试使用 dup2,所以我有点困惑。 另外,不要介意 printfs,它们只是用于调试。 非常感谢!

【问题讨论】:

    标签: c shell pipe dup2


    【解决方案1】:

    基本上,您必须在正确的位置关闭管道,并且您未能在 switch 语句中关闭括号。代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/wait.h> /*lib for waitpid()*/
    
    int main(void) {
        int pfd1[2];
        int pfd2[2];
        pid_t pid1, pid2, pid3;
        if(pipe(pfd1)==-1) {
            perror("Creazione pipe");
            exit(EXIT_FAILURE);
            }
        if(pipe(pfd2)==-1) {
            perror("Creazione pipe");
            exit(EXIT_FAILURE);
            }
        printf("Sono il padre\n");
        switch(pid1=fork()) {
            printf("%d\n", pid1);
            case -1: {
                perror("Creazione figlio 1");
                exit(EXIT_FAILURE);
                }
            case 0: { //figlio 1
                printf("Sono il figlio 1\n");
                if(dup2(pfd1[1],1)==-1) { //redirige lo stdout sul descrittore scrittura
                    perror("Prima redirezione");
                    exit(EXIT_FAILURE);
                    }
                close(pfd1[0]);
                close(pfd1[1]); //lo chiudo perchè sto redirigendo lo stdout
                close(pfd2[0]);
                close(pfd2[1]);
                execlp("ps", "ps", "-A", "-ostat,pid", (char*) NULL);
                }
            }
        waitpid(pid1,NULL,0);
        switch(pid2=fork()) {
            case -1: {
                perror("Creazione figlio 2");
                exit(EXIT_FAILURE);
                }
            case 0: { //figlio 2
                printf("Sono il figlio 2\n");
                if(dup2(pfd1[0],0)==-1) { //redirige lo stdin sul descrittore lettura
                    perror("Seconda redirezione");
                    exit(EXIT_FAILURE);
                    }
                printf("Prima redirezione figlio 2\n");
                if(dup2(pfd2[1],1)==-1) {
                    perror("Terza redirezione");
                    exit(EXIT_FAILURE);
                    }
                close(pfd1[0]);
                close(pfd1[1]);
                close(pfd2[0]);
                close(pfd2[1]);
                execlp("grep", "grep", "-e", "[Ss]", (char*) NULL);
                }
    
        } /*You forgot that bracket*/
        /*
         * Close the pipe before waitpid because 2rd child
         * will wait until you close it. Check pipe theory
         */
        close(pfd1[1]);
        close(pfd1[0]);
        waitpid(pid2, NULL,0);
        switch(pid3=fork()) {
            case -1: {
                perror("Creazione terzo figlio");
                exit(EXIT_FAILURE);
                }
            case 0: { //figlio 3
                printf("Sono il figlio 3\n");
                if(dup2(pfd2[0],0)==-1) {
                    perror("Quarta redirezione");
                    exit(EXIT_FAILURE);
                    }
                close(pfd2[0]);
                close(pfd2[1]);
                /*' ' removed from the "{print $2}"*/
                execlp("awk", "awk", "{print $2}", (char*) NULL);
                }
        }
        /*
         * Close the pipe before waitpid because 3rd child
         * will wait until you close it. Check pipe theory
         */
        close(pfd2[0]);
        close(pfd2[1]);
        waitpid(pid3, NULL, 0);
    
    
        return 0;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-26
      • 2015-07-03
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多