2017-04-14 49 views
1

我想獲得一個工作在C代碼而不是調用命令行查找的套接字。C:unix套接字 - >破管

傳遞給child2函數'cut'的孩子3'sort'函數工作正常,並且當執行時包含所有3個子函數時,程序在父進程waitpid()中卡住。

我試圖隔離參與套接字的唯一孩子,當我在gdb上運行可執行文件時,我收到消息「find:'standard output':Broken pipe」和「find:write error」

這裏的兩個子功能與套接字交互的例子: 兒童1:

void child1() 
{ 
    int sock; 
    struct sockaddr_un remote; 

    sock = socket(AF_UNIX, SOCK_STREAM, 0) 
    memset(&remote, 0, sizeof(struct sockaddr_un)); 
    remote.sun_family = AF_UNIX; 
    strncpy(remote.sun_path, "socket", sizeof(remote.sun_path) - 1); 

    while((connect(sock, (struct sockaddr *)&remote, (socklen_t)sizeof(remote))) == -1) 
    { 
     if(errno != ENOENT && errno != ECONNREFUSED) 
      erro("child 2 failed to connect to socket"); 
    } 
    dup2(sock, 1); 
    close(sock); 
    execlp("find", "find", ".", "-type" , "f", "-ls", NULL); 
} 

而且CHILD2:

void child2(int *pipe_fd) 
{ 
    int sock; 
    struct sockaddr_un local, remote; 
    socklen_t sock_size = (socklen_t)sizeof(remote); 

    sock= socket(AF_UNIX, SOCK_STREAM, 0); 

    memset(&local, 0, sizeof(struct sockaddr_un)); 
    memset(&remote, 0, sizeof(struct sockaddr_un)); 

    local.sun_family = AF_UNIX; 
    strncpy(local.sun_path, "socket", sizeof(local.sun_path) - 1); 
    unlink("socket"); 
    bind(sock, (struct sockaddr *)&local, sizeof(struct sockaddr_un)); 

    listen(sock, 1); 
    sock = accept(sock,(struct sockaddr *)&remote, &sock_size)); 
    dup2(sock, STDOUT_FILENO); 
    close(sock); 

    close(pipe_fd[0]); 
    dup2(pipe_fd[1],1); 
    close(pipe_fd[1]); 
    execlp("cut", "cut", "-d", " ", "-f", "3-", NULL); 
} 

沒有什麼東東d在具體解決這個問題時,我只是想了解我在創建過程中做了什麼錯誤,所以我不會在將來再做這件事。 我預先提供任何幫助。

+0

兩個孩子都在寫同一個插座。那真的是你想要的嗎? – Barmar

+0

'child2'永遠不會執行任何操作。 – Barmar

+1

爲什麼'child2'將stdout連接到套接字?它不應該是讀者嗎? – Barmar

回答

2

如果我改變dup2(sock, STDOUT_FILENO);dup2(sock, STDIN_FILENO);child2(輸入有襪子,輸出是導致child3管),您的實例主要作品:

(檢查所需的錯誤)

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <sys/un.h> 
#include <sys/wait.h> 
void child1() 
{ 
    int sock; 
    struct sockaddr_un remote; 

    sock = socket(AF_UNIX, SOCK_STREAM, 0); 
    memset(&remote, 0, sizeof(struct sockaddr_un)); 
    remote.sun_family = AF_UNIX; 
    strncpy(remote.sun_path, "socket", sizeof(remote.sun_path) - 1); 

    while((connect(sock, (struct sockaddr *)&remote, (socklen_t)sizeof(remote))) == -1) 
    { 
     perror("connect"); 
     if(errno != ENOENT && errno != ECONNREFUSED) 
      perror("child 2 failed to connect to socket"); 
    } 
    dup2(sock, 1); 
    close(sock); 
    execlp("find", "find", ".", "-type" , "f", "-ls", (char*)0); 
} 
void child2(int *pipe_fd) 
{ 
    int sock; 
    struct sockaddr_un local, remote; 
    socklen_t sock_size = (socklen_t)sizeof(remote); 

    sock= socket(AF_UNIX, SOCK_STREAM, 0); 

    memset(&local, 0, sizeof(struct sockaddr_un)); 
    memset(&remote, 0, sizeof(struct sockaddr_un)); 

    local.sun_family = AF_UNIX; 
    strncpy(local.sun_path, "socket", sizeof(local.sun_path) - 1); 
    unlink("socket"); 
    bind(sock, (struct sockaddr *)&local, sizeof(struct sockaddr_un)); 

    listen(sock, 1); 
    puts("listened"); 
    sock = accept(sock,(struct sockaddr *)&remote, &sock_size); 
    dup2(sock, STDIN_FILENO); 
    close(sock); 

    close(pipe_fd[0]); 
    dup2(pipe_fd[1],1); 
    close(pipe_fd[1]); 
    execlp("cut", "cut", "-d", " ", "-f", "3-", (char*)0); 
} 
void child3(int *pipe_fd) 
{ 
    dup2(pipe_fd[0],0); 
    close(pipe_fd[0]); 
    execlp("sort", "sort", (char*)0); 
} 

int main() 
{ 
    int pi[2]; 
    pid_t pid0, pid1, pid2; 
    pid0 = fork(); 
    if (0==pid0){ 
     child1(); 
     _exit(1); 
    } 
    pipe(pi); 
    pid1 = fork(); 
    if(0==pid1){ 
     child2(pi); 
     _exit(1); 
    } 
    close(pi[1]); 
    pid2 = fork(); 
    if(0==pid2){ 
     child3(pi); 
     _exit(1); 
    } 
    close(pi[0]); 

    wait(0); 
    wait(0); 
    wait(0); 
} 

這將是基本上是三重管:

find | cut | sort 

其中第一|不是常規管道,而是通過"socket"的UNIX套接字連接。

+0

謝謝!我真的需要設定我的想法來檢查這些錯誤。 – Aereth