2017-04-14 13 views
1

私は、コマンドラインfindを呼び出す代わりに、Cコードで動作するソケットを取得しようとしています。C:unix socket - > broken pipe

child2関数 'cut'にパイプされたchild3'sort '関数はうまく動作し、プログラムは実行時に3つの子関数がすべて含まれていると、親プロセスwaitpid()にスタックされます。 「見つける:書き込みエラー」と

が、私はソケットに参加し、私はGDBの実行可能ファイルを実行したとき、私はメッセージを取得一人っ子を隔離しようとした「壊れたパイプ:: 『標準出力』を見つける」

ここ

は、ソケットとの対話2つの関数の例です: 子供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); 
} 

何の旧姓はありませんこの問題を具体的に解決するために、私は作成プロセスで何が間違っているのかを理解しようとしているので、今後はやり直しません。 私は事前に助けて頂きたいと思います。

+0

両方の子供が同じソケットに書き込んでいます。それは本当にあなたが望むものですか? – Barmar

+0

'child2'は何も実行しません。 – Barmar

+1

'child2'がソケットにstdoutを接続するのはなぜですか?読者ではないと思いますか? – Barmar

答えて

2

私はchild2dup2(sock, STDIN_FILENO);dup2(sock, STDOUT_FILENO);を変更した場合(入力が靴下であり、出力は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