パイプとFIFO

  • パイプは名前を持たないため、(親子)関係があるプロセス間でしか使用できないという根本的な制限がある

  • この制限は、FIFO、名前付きパイプで解決された。
  • パイプ

    パイプはpipe関数で作成され、単方向(unidirectional)のデータの流れを提供する

    #include <unistd.h>
    
    int pipe(int fd[2]);
    
    戻り値:成功なら0、エラーなら-1

    成功した場合には、読み出しモードでオープンされているfd[0]と、書き込みモードでオープンされているfd[1]の2つのディスクリプタが返される。

    S_ISFIFOマクロでディスクリプタがパイプであるかどうかを検査できる。S_ISFIFOマクロはstat構造体のst_modeメンバを単一の引数として持ち、評価結果は真(非ゼロ)か偽(ゼロ)となる。

    //パイプによるエコーサーバー/クライアント
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    
    void
    echo_server(int readfd, int writefd)
    {
            char buff[32];
            int n;
    
            n = read(readfd, buff, sizeof(buff));
            printf("read bytes : %d\n", n);
            buff[n] = '\0';        
            printf("server received : %s", buff);
            flush(stdout);
    }
    
    void
    echo_client(int readfd, int writefd)
    {
            char buff[1024];
            int n;
    
            fgets(buff, sizeof(buff), stdin);
            n = write(writefd, buff, strlen(buff));
            printf("write bytes : %d\n", n);
    }
    
    int
    main()
    {
            int pipe1[2];
            int pipe2[2];
            pid_t childpid;
    
            pipe(pipe1);
            pipe(pipe2);
    
            if ( (childpid = fork()) == 0 ) {//Child
                    close(pipe1[1]);
                    close(pipe2[0]);
                    echo_server(pipe1[0], pipe2[1]);
                    exit(1);
            }
           
            //Parent
            close(pipe1[0]);
            close(pipe2[1]);
            echo_client(pipe2[0], pipe1[1]);
           
            waitpid(childpid, NULL, 0);
           
            return 0;
    }
    


    参考文献:UNIXネットワークプログラミング Vol.2 スティーブンズ