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

名前

       splice - パイプとの間でデータを継ぎ合わせる

書式

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

       ssize_t splice(int fd_in, loff_t *off_in, int fd_out,
                      loff_t *off_out, size_t len, unsigned int flags);

説明

       splice()  は、カーネルアドレス空間とユーザーアドレス空間との間のコピーを伴わずに、 2 つのファイルディスク
       リプター間でデータの移動を行う。 ファイルディスクリプター fd_in からファイルディスクリプター fd_out  へ最
       大 len バイトを転送する。 2 つのファイルディスクリプターのうち一つは パイプを参照していなければならない。

       fd_inoff_in には以下のルールが適用される。

       *  fd_in がパイプを参照している場合、 off_in は NULL でなければならない。

       *  fd_in がパイプを参照しておらず、かつ off_in が NULL の場合、 バイトは fd_in の現在のファイルオフセット
          から読み出され、 現在のファイルオフセットは適切に調整される。

       *  fd_in がパイプを参照しておらず、 off_in が NULL でない場合、 off_infd_in  からのデータ読み出しを開
          始する先頭オフセットを格納したバッファー  へのポインターでなければならない。この場合、  fd_in の現在の
          ファイルオフセットは変更されない。

       fd_outoff_out に関しても同様である。

       flags 引き数には、以下の値の 0 個以上をビット毎の論理和の形で指定する。

       SPLICE_F_MOVE      ページのコピーでなく移動を試みる。    これはカーネルに対するヒントでしかない。    つま
                          り、カーネルがパイプからページを移動できない場合や、  パイプバッファーがページ全部を参
                          照していない場合は、 ページのコピーが行われることもある。 このフラグの最初の実装にはバ
                          グがあった。そのため、 Linux 2.6.21 以降ではこのフラグの操作はできないようになっている
                          (ただし、 splice() コールでこのフラグを指定することは今も認められている)。  将来、正し
                          い実装が行われることだろう。

       SPLICE_F_NONBLOCK  入出力時に停止 (block) しない。 このフラグを指定すると、 splice によるパイプ操作を非停
                          止モード (nonblocking) で  行おうとするが、その場合でも  splice()   は停止することもあ
                          る。なぜなら、データのやり取りを行う  ファイルディスクリプターは  (O_NONBLOCK フラグを
                          セットされていない場合) 停止する可能性があるからである。

       SPLICE_F_MORE      この後の splice でさらに転送されるデータがあることを示す。  このフラグは  fd_out  がソ
                          ケットを参照している場合に有用なヒントとなる  (send(2)   の  MSG_MOREtcp(7)   の
                          TCP_CORK の説明も参照)。

       SPLICE_F_GIFT      splice()  では使用しない。 vmsplice(2)  参照。

返り値

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

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

エラー

       EAGAIN SPLICE_F_NONBLOCKflags に指定されていて、かつ操作が停止するような状態であった。

       EBADF  ファイルディスクリプターの一方または両方が有効ではない、  もしくは適切な  read-write  モードではな
              い。

       EINVAL 対象のファイルシステムが  splice に対応していない、 または対象のファイルが追記モードでオープンされ
              ている、 またはディスクリプターのどちらもパイプを参照していない、 または seek できないデバイスに対
              してオフセットが指定された。

       ENOMEM メモリー不足。

       ESPIPE off_inoff_out のいずれかが NULL ではないが、対応するファイルディスクリプターが パイプを参照し
              ている。

バージョン

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

準拠

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

注意

       3 つのシステムコール (splice(), vmsplice(2), tee(2)) を使うと、ユーザー空間プログラムは任意のカーネルバッ
       ファーに対する  完全な制御ができる。カーネルバッファーは、パイプに使用されているのと   同種のバッファーを
       使ってカーネル内に実装されている。 大まかにいうと、これらのシステムコールは以下の仕事を行う:

       splice()    バッファーから任意のファイルディスクリプターや、その逆方向、   もしくはあるバッファーから別の
                   バッファーへの、データ移動を行う。

       tee(2)      あるバッファーから別のバッファーへのデータ「コピー」を行う。

       vmsplice(2) ユーザー空間からバッファーへのデータ「コピー」を行う。

       ここではコピーの話をしているが、実際のコピーは一般的に回避される。 カーネルは、パイプバッファーをカーネル
       メモリーのページへのポインター集合として 実装し、ページへの参照回数を管理することで、これを実現している。
       カーネルは、対象となるページを参照する (出力バッファー用の) ポインターを 新規に作成することでバッファー内
       のページの「コピー」を作成し、   そのページの参照回数を増やす。つまり、ポインターだけがコピーされ、  バッ
       ファーのページはコピーされない。

       tee(2)  参照。

関連項目

       sendfile(2), tee(2), vmsplice(2)

この文書について

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