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

名前
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 には以下のルールが適用される。
* fd_in がパイプを参照している場合、 off_in は NULL でなければならない。
* fd_in がパイプを参照しておらず、かつ off_in が NULL の場合、 バイトは fd_in の現在のファイルオフセット
から読み出され、 現在のファイルオフセットは適切に調整される。
* fd_in がパイプを参照しておらず、 off_in が NULL でない場合、 off_in は fd_in からのデータ読み出しを開
始する先頭オフセットを格納したバッファー へのポインターでなければならない。この場合、 fd_in の現在の
ファイルオフセットは変更されない。
fd_out と off_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_MORE や tcp(7) の
TCP_CORK の説明も参照)。
SPLICE_F_GIFT splice() では使用しない。 vmsplice(2) 参照。
返り値
成功して完了すると、 splice() はパイプから出し入れしたバイト数を返す。 返り値 0 はデータの転送が行わな
かったことを示す。 この場合、処理を停止 (block) しても無意味である。 なぜなら、 fd_in が参照するパイプの
書き込み側に接続されている者がいないからである。
エラーの場合、 splice() は -1 を返し、 errno にエラーを示す値を設定する。
エラー
EAGAIN SPLICE_F_NONBLOCK が flags に指定されていて、かつ操作が停止するような状態であった。
EBADF ファイルディスクリプターの一方または両方が有効ではない、 もしくは適切な read-write モードではな
い。
EINVAL 対象のファイルシステムが splice に対応していない、 または対象のファイルが追記モードでオープンされ
ている、 またはディスクリプターのどちらもパイプを参照していない、 または seek できないデバイスに対
してオフセットが指定された。
ENOMEM メモリー不足。
ESPIPE off_in か off_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/ に書かれている。
Linux 2014-12-31 SPLICE(2)