Provided by: manpages-ja-dev_0.5.0.0.20140515+dfsg-2_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_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 にエラーを示す値を設定する。

エラー

       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.65 の一部  である。プロジェクト
       の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。