簡體   English   中英

用dup2創建管道

[英]Creating a pipe with dup2

#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個孩子,並使他們通過兩個管道進行交流。 每個孩子執行命令的一部分。 問題是我的程序卡在了第二個孩子上,后者顯然根本無法執行。 我確定我的代碼存在一些問題,但是由於這是我第一次嘗試使用dup2,所以我有些困惑。 另外,不要介意printfs,它們僅用於調試。 非常感謝!

基本上,您必須在正確的位置關閉管道,而無法在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;
    }

暫無
暫無

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

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