UIO(9) FreeBSD カーネル開発者マニュアル UIO(9)
名称
uio, uiomove − デバイスドライバ入出力ルーチン |
書式
#include <sys/types.h> struct uio { |
struct |
iovec *uio_iov; |
||
int |
uio_iovcnt; |
||
off_t |
uio_offset; |
||
int |
uio_resid; |
||
enum |
uio_seg uio_segflg; |
||
enum |
uio_rw uio_rw; |
||
struct |
thread *uio_td; |
}; int |
uiomove(void *buf, int howmuch, struct uio *uiop); |
解説 |
uiomove() 関数は、ユーザ空間とカーネル空間の境界を越えることさえ可能で、 バッファと入出力ベクタ間のデータ転送の実行に使用されます。 文字型デバイスのドライバに渡された、あらゆる read(2), write(2), readv(2) ないし writev(2) システムコールの結果として、適切なドライバの d_read また は d_write エントリが struct uio 構造体のポインタを渡されて呼び出されま す。転送のリクエストは、この構造体の中にエンコードされます。ドライバ自身 もこの構造体の中のデータを取り出すために uiomove() を使用するべきです。 uio 構造体の各フィールドは下記のとおりです。 |
uio_iov
処理すべき入出力ベクタの配列です。散在的な入出力の場合には、 一つ以上のベクタとなるでしょう。 uio_iovcnt uio_offset uio_resid uio_segflg UIO_USERSPACE UIO_SYSSPACE UIO_NOCOPY uio_rw uio_procp 使用例 |
考え方として、ドライバはデータのためのプライベートなバッファの保守を行な い、このバッファの最大サイズのデータのかたまりの要求を処理します。下記の バッファの取り扱いはとても簡略化されていて恐らく動きません(バッファのポイ ンタは部分的な読み込みの場合進みません)し、 uio の取り扱いを実際にやって 見せているだけだ、ということに注意してください。 /* MIN() の定義はこの中にあります */ #include <sys/param.h> #define BUFSIZE 512 static char buffer[BUFSIZE]; |
static int data_available; |
/* 読み込めるデータ量 */ |
static int |
int rv, amnt; |
|||||||
rv = 0; |
|||||||
while (uio->uio_resid > 0) { |
|||||||
if (data_available > 0) { |
|||||||
amnt = MIN(uio->uio_resid, data_available); |
|||||||
rv = uiomove(buffer, amnt, uio); |
|||||||
if (rv != 0) |
|||||||
break; |
|||||||
data_available -= amnt; |
|||||||
} else |
|||||||
tsleep(...); |
/* より良い時期まで待つ */ |
||||||
} |
|||||||
if (rv != 0) { |
|||||||
/* エラーのクリーンアップをここで行なう */ |
|||||||
} |
|||||||
return (rv); |
} |
戻り値
uiomove() はプロセスのアドレス空間との転送の場合に、 copyin(9) または copyout(9) によって引き起こされた EFAULT を返すことがあります。 |
関連項目
read(2), readv(2), write(2), writev(2), copyin(9), copyout(9), sleep(9) |
歴史
uio の仕組みはある早期のバージョンの UNIX で登場しました。 |
作者
このマニュアルページは Jörg Wunsch が書きました。 FreeBSD 10.0 February 2, 1997 FreeBSD 10.0 |