SPLICE(2) | Linux Programmer's Manual | SPLICE(2) |
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_out と off_out に関しても同様である。
flags 引き数には、以下の値の 0 個以上をビット毎の論理和の形で指定する。
成功して完了すると、 splice() はパイプから出し入れしたバイト数を返す。 返り値 0 はデータの転送が行わなかったことを示す。 この場合、処理を停止 (block) しても無意味である。 なぜなら、 fd_in が参照するパイプの書き込み側に接続されている者がいないからである。
エラーの場合、 splice() は -1 を返し、 errno にエラーを示す値を設定する。
splice() システムコールは Linux 2.6.17 で初めて登場した。 ライブラリによるサポートは glibc バージョン 2.5 で追加された。
このシステムコールは Linux 固有である。
3 つのシステムコール (splice(), vmsplice(2), tee(2)) を使うと、ユーザー空間プログラムは任意のカーネルバッファーに対する 完全な制御ができる。カーネルバッファーは、パイプに使用されているのと 同種のバッファーを使ってカーネル内に実装されている。 大まかにいうと、これらのシステムコールは以下の仕事を行う:
ここではコピーの話をしているが、実際のコピーは一般的に回避される。 カーネルは、パイプバッファーをカーネルメモリーのページへのポインター集合として 実装し、ページへの参照回数を管理することで、これを実現している。 カーネルは、対象となるページを参照する (出力バッファー用の) ポインターを 新規に作成することでバッファー内のページの「コピー」を作成し、 そのページの参照回数を増やす。つまり、ポインターだけがコピーされ、 バッファーのページはコピーされない。
tee(2) 参照。
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
2014-12-31 | Linux |