SPLICE
Section: Linux Programmer's Manual (2)
Updated: 2006-04-28
Index
JM Home Page
roff page
名前
splice - パイプとの間でデータを継ぎ合わせる
書式
#define _GNU_SOURCE
#include <fcntl.h>
long splice(int fd_in, off_t *off_in, int fd_out,
off_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_in
は
fd_in
からのデータ読み出しを開始する先頭オフセットを格納したバッファ
へのポインタでなければならない。この場合、
fd_in
の現在のファイルオフセットは変更されない。
fd_out
と
off_out
に関しても同様である。
flags
引き数には、以下の値の 0 個以上のビット単位の論理和を
とったものを指定する:
- SPLICE_F_MOVE
-
ページのコピーでなく移動を試みる。
これはカーネルに対するヒントでしかない。
つまり、カーネルがパイプからページを移動できない場合や、
パイプバッファがページ全部を参照していない場合は、
ページのコピーが行われることもある。
- SPLICE_F_NONBLOCK
-
入出力時に停止 (block) しない。
このフラグを指定すると、
splice によるパイプ操作を非停止モード (non-blocking) で
行おうとするが、その場合でも
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
にエラーを示す値を設定する。
エラー
- EBADF
-
ファイルディスクリプタの一方または両方が有効ではない、
もしくは適切な read-write モードではない。
- EINVAL
-
対象のファイルシステムが splice に対応していない、
またはディスクリプタのどちらもパイプを参照していない、
または seek できないデバイスに対してオフセットが指定された。
- ENOMEM
-
メモリ不足。
- ESPIPE
-
off_in
か
off_out
のいずれかが NULL ではないが、対応するファイルディスクリプタが
パイプを参照している。
バージョン
splice(2)
システムコールは Linux 2.6.17 で初めて登場した。
準拠
このシステムコールは Linux 固有である。
注意
3 つのシステムコール
(splice(2),
vmsplice(2),
tee(2))
を使うと、ユーザ空間プログラムは任意のカーネルバッファに対する
完全な制御ができる。カーネルバッファは、パイプに使用されているのと
同種のバッファを使ってカーネル内に実装されている。
大まかにいうと、これらのシステムコールは以下の仕事を行う:
- splice()
-
バッファから任意のファイルディスクリプタや、その逆方向、
もしくはあるバッファから別のバッファへの、データ移動を行う。
- tee(2)
-
あるバッファから別のバッファへのデータ「コピー」を行う。
- vmsplice(2)
-
ユーザ空間からバッファへのデータ「コピー」を行う。
ここではコピーの話をしているが、実際のコピーは一般的に回避される。
カーネルは、パイプ・バッファをカーネルメモリのページへのポインタ集合として
実装し、ページへの参照回数を管理することで、これを実現している。
カーネルは、対象となるページを参照する (出力バッファ用の) ポインタを
新規に作成することでバッファ内のページの「コピー」を作成し、
そのページの参照回数を増やす。つまり、ポインタだけがコピーされ、
バッファのページはコピーされない。
例
tee(2)
参照。
関連項目
sendfile(2),
splice(2),
tee(2),
feature_test_macros(7)
Index
- 名前
-
- 書式
-
- 説明
-
- 返り値
-
- エラー
-
- バージョン
-
- 準拠
-
- 注意
-
- 例
-
- 関連項目
-
This document was created by
man2html,
using the manual pages.
Time: 04:32:04 GMT, November 19, 2007