pipe:splice/teeサンプル


[root@localhost north]# cat pipe.c
#define _GNU_SOURCE

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/syscall.h>

void	pipe_print(int pfd, char* pfdtype);
void	write_pipe1();
void	pipe_splice(int cnt);
void	pipe_tee(int cnt);
void	pipe_read_write(int cnt);

int   pfd1[2], pfd2[2];
char 	*pdata = "1234567890";

void main(int argc, char *argv[])
{ 
    pipe2(pfd1, O_NONBLOCK);
    pipe2(pfd2, O_NONBLOCK);

    int cnt = atoi(argv[2]);
    write_pipe1();
    if(!strcmp(argv[1], "READ_WRITE")) {
        pipe_read_write(cnt);
     }
    if(!strcmp(argv[1], "SPLICE")) {
        pipe_splice(cnt);
     }
    if(!strcmp(argv[1], "TEE")) {
        pipe_tee(cnt);
     }

    pipe_print(pfd1[0], "pfd1");
    pipe_print(pfd2[0], "pfd2");
    printf("\n");
}

void	pipe_read_write(int cnt)
{
    char	buff[64];

    cnt = read(pfd1[0], buff, cnt);
    write(pfd2[1], buff, cnt);
}

void	pipe_splice(int cnt)
{
    splice(pfd1[0], NULL, pfd2[1], NULL, cnt, 0);
}

void	pipe_tee(int cnt)
{
    syscall(SYS_tee, pfd1[0], pfd2[1], cnt, 0);
}

void	write_pipe1()
{
    write(pfd1[1], pdata, strlen(pdata));
}

void	pipe_print(int pfd, char* pname)
{
    char	buff[64];

    int cnt = read(pfd, buff, 64);
    buff[cnt] = 0;
    printf("%s -> %s\n", pname, buff);
}

[root@localhost north]# ./pipe.out READ_WRITE 1
pfd1 -> 234567890
pfd2 -> 1
[root@localhost north]# ./pipe.out READ_WRITE 2
pfd1 -> 34567890
pfd2 -> 12

[root@localhost north]# ./pipe.out SPLICE 1
pfd1 -> 234567890
pfd2 -> 1
[root@localhost north]# ./pipe.out SPLICE 2
pfd1 -> 34567890
pfd2 -> 12

[root@localhost north]# ./pipe.out TEE 1
pfd1 -> 1234567890
pfd2 -> 1
[root@localhost north]# ./pipe.out TEE 2
pfd1 -> 1234567890
pfd2 -> 12

備考

struct pipe_inode_info {
       wait_queue_head_t wait;
       unsigned int nrbufs, curbuf, buffers;
       unsigned int readers;
       unsigned int writers;
       unsigned int waiting_writers;
       unsigned int r_counter;
       unsigned int w_counter;
       struct page *tmp_page;
       struct fasync_struct *fasync_readers;
       struct fasync_struct *fasync_writers;
       struct inode *inode;
       struct pipe_buffer *bufs;
};
curbufは読込み開始位置、nrbufsは読込みバッファバイト数、read/spliceは、読込んだサイズ数が減少され、読込み開始位置のcurbufが更新されるが、 teeは係る実装はされてない。

最終更新 2017/12/18 13:33:24 - north
(2017/12/18 12:16:59 作成)