TEE

Section: Linux Programmer's Manual (2)
Updated: 2014-12-31
Index JM Home Page roff page
 

名前

tee - パイプの中身を複製する  

書式

#define _GNU_SOURCE         /* feature_test_macros(7) 参照 */
#include <fcntl.h>

ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);
 

説明

tee() は、ファイルディスクリプター fd_in が参照するパイプからファイルディスクリプター fd_out が参照するパイプへ最大 len バイトのデータを複製する。 この操作では、複製されるデータは fd_in からは消費されない。したがって、これらのデータをこの後の splice(2) でコピーすることができる。

flags は一連の修飾フラグであり、 splice(2) や vmsplice(2) と共通の名前である。

SPLICE_F_MOVE
現在のところ tee() では何の効果もない。 splice(2) 参照。
SPLICE_F_NONBLOCK
入出力で停止 (block) しない。詳細は splice(2) 参照。
SPLICE_F_MORE
現在のところ tee() では何の効果もないが、将来的には実装される可能性がある。 splice(2) 参照。
SPLICE_F_GIFT
tee() では未使用。 vmsplice(2) 参照。
 

返り値

成功して完了すると、 tee() は入出力間で複製されたバイト数を返す。 返り値 0 はデータの転送が行われなかったことを示す。 この場合、処理を停止 (block) しても無意味である。 なぜなら、 fd_in が参照するパイプの書き込み側に接続されている者がいないからである。

エラーの場合、 tee() は -1 を返し、 errno にエラーを示す値を設定する。  

エラー

EAGAIN
SPLICE_F_NONBLOCKflags に指定されていて、かつ操作が停止するような状態であった。
EINVAL
fd_infd_out のどちらかがパイプを参照していない。もしくは fd_infd_out が同じパイプを参照している。
ENOMEM
メモリー不足。
 

バージョン

tee() システムコールは Linux 2.6.17 で初めて登場した。 ライブラリによるサポートは glibc バージョン 2.5 で追加された。  

準拠

このシステムコールは Linux 固有である。  

注意

概念としては、 tee() は二つのパイプ間でデータのコピーを行う。 しかし、実際には実データのコピーは行われない。 内部では、 tee() は入力側に対する参照だけを作成することで出力側にデータを 追加する。  

以下の例は、 tee() システムコールを使って、 基本的な tee(1) プログラムを実装したものである。 以下は利用例である。

$ date |./a.out out.log | cat
Tue Oct 28 10:06:00 CET 2014
$ cat out.log
Tue Oct 28 10:06:00 CET 2014
 

プログラムのソース


#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>

int
main(int argc, char *argv[])
{
    int fd;
    int len, slen;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s <file>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    do {
        /*
         * tee stdin to stdout.
         */
        len = tee(STDIN_FILENO, STDOUT_FILENO,
                  INT_MAX, SPLICE_F_NONBLOCK);

        if (len < 0) {
            if (errno == EAGAIN)
                continue;
            perror("tee");
            exit(EXIT_FAILURE);
        } else
            if (len == 0)
                break;

        /*
         * Consume stdin by splicing it to a file.
         */
        while (len > 0) {
            slen = splice(STDIN_FILENO, NULL, fd, NULL,
                          len, SPLICE_F_MOVE);
            if (slen < 0) {
                perror("splice");
                break;
            }
            len -= slen;
        }
    } while (1);

    close(fd);
    exit(EXIT_SUCCESS);
}
 

関連項目

splice(2), vmsplice(2)  

この文書について

この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。


 

Index

名前
書式
説明
返り値
エラー
バージョン
準拠
注意
プログラムのソース
関連項目
この文書について

This document was created by man2html, using the manual pages.
Time: 03:33:27 GMT, March 14, 2018