Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       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 is a bit mask that is composed by ORing together zero or more of the following values:

       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_NONBLOCK was specified in flags or one  of  the  file  descriptors  had  been  marked  as
              nonblocking (O_NONBLOCK), and the operation would block.

       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), pipe(7)

この文書について

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

Linux                                              2020-06-09                                             TEE(2)