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 個以上をビット毎の論理和の形で指定する。
Upon successful completion, splice() returns the number of bytes spliced to or from the pipe.
A return value of 0 means end of input. If fd_in refers to a pipe, then this means that there was no data to transfer, and it would not make sense to block because there are no writers connected to the write end of the pipe.
エラーの場合、 splice() は -1 を返し、 errno にエラーを示す値を設定する。
splice() システムコールは Linux 2.6.17 で初めて登場した。 ライブラリによるサポートは glibc バージョン 2.5 で追加された。
このシステムコールは Linux 固有である。
3 つのシステムコール (splice(), vmsplice(2), tee(2)) を使うと、ユーザー空間プログラムは任意のカーネルバッファーに対する 完全な制御ができる。カーネルバッファーは、パイプに使用されているのと 同種のバッファーを使ってカーネル内に実装されている。 大まかにいうと、これらのシステムコールは以下の仕事を行う:
ここではコピーの話をしているが、実際のコピーは一般的に回避される。 カーネルは、パイプバッファーをカーネルメモリーのページへのポインター集合として 実装し、ページへの参照回数を管理することで、これを実現している。 カーネルは、対象となるページを参照する (出力バッファー用の) ポインターを 新規に作成することでバッファー内のページの「コピー」を作成し、 そのページの参照回数を増やす。つまり、ポインターだけがコピーされ、 バッファーのページはコピーされない。
In Linux 2.6.30 and earlier, exactly one of fd_in and fd_out was required to be a pipe. Since Linux 2.6.31, both arguments may refer to pipes.
tee(2) 参照。
copy_file_range(2), sendfile(2), tee(2), vmsplice(2), pipe(7)
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。
2020-06-09 | Linux |