VOP_READDIR(9)

名称
VOP_READDIR - ディレクトリ内容の読込み

書式
<sys/param.h> <sys/dirent.h> <sys/vnode.h> int VOP_READDIR(struct vnode *vp, struct uio *uio, struct ucred *cred, int *eofflag, int *ncookies, u_long **cookies)

解説
ディレクトリエントリを読込みます。

vp  ディレクトリの vnode です。

uio ディレクトリ内容を読込む場所です。

cred
    呼び出し側の証明です。

eofflag
    ファイル終端の状態を返します (必要なければ NULL)。

ncookies
    NFS のために作成されたディレクトリクッキーの数です (必要なければ NULL)。

cookies
    NFS のためのディレクトリ検索クッキーです (必要なければ NULL)。

ディレクトリ内容は struct dirent 構造体に読込まれます。 ディスク上の構造体がこれと違っている場合、変換が必要となります。

ロック
ディレクトリはエントリ時にロックされているべきであり、 終了時までロックされます。

戻り値
成功時には 0 が返され、そうでなければエラーコードが返されます。

NFS サーバから呼び出された場合には、追加の引数 eofflag, ncookies および cookies が与えられます。 *eofflag の値は、読込み中にディレクトリの最後に達した場合には、 TRUE に設定されるべきです。 ディレクトリ検索クッキーは NFS クライアントに返され、後でそのディレクトリを 通してディレクトリの読込みを再開するために使用されることが出来ます。 ディレクトリエントリ毎に 1 つのクッキーが返されるべきです。 クッキーの値は、ディレクトリ内のオフセットであり、 対応するディスク上のディレクトリエントリがそこから開始します。 クッキーのためのメモリは以下を使用して割り当てられるべきです。

    	...;
    	*ncookies = number of entries read;
    	*cookies = (u_int*)#
    		malloc(*ncookies * sizeof(u_int), M_TEMP, M_WAITOK);

疑似コード

    int
    vop_readdir(struct vnode *vp, struct uio *uio, struct ucred *cred,
    	    int *eofflag, int *ncookies, u_int **cookies)
    {
        off_t off;
        int error = 0;
        /*
         * クッキーの生成時に後で使うために元のオフセットを覚えます。
         */
        off = uio->uio_offset;
        /*
         * uio->uio_offset から始まるディレクトリ内容を uio によって
         * 指されるバッファに読込みます。
         */
        ...;
        if (!error && ncookies != NULL) {
    	struct dirent *dpStart;
    	struct dirent *dpEnd;
    	struct dirent *dp;
    	int count;
    	u_int *cookiebuf;
    	u_int *cookiep;
    	if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
    	    panic("vop_readdir: unexpected uio from NFS server");
    	/*
    	 * 今 uio に読込んだ要素を解析します。
    	 */
    	dpStart = (struct dirent *)
    	    ((char *)uio->uio_iov->iov_base - (uio->uio_offset - off));
    	dpEnd = (struct dirent *) uio->uio_iov->iov_base;
    	/*
    	 * エントリ数の数え上げ
    	 */
    	for (dp = dpStart, count = 0;
    	     dp < dpEnd;
    	     dp = (struct dirent *)((caddr_t) dp + dp->d_reclen))
    	    count++;
    	cookiebuf = (u_int *) malloc(count * sizeof(u_int), M_TEMP, M_WAITOK);
    	for (dp = dpStart; cookiep = cookiebuf;
    	     dp < dpEnd;
    	     dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) {
    	    off += dp->d_reclen;
    	    *cookiep++ = (u_int) off;
    	}
    	*ncookies = count;
    	*cookies = cookiebuf;
        }
        if (eofflag && uio->uio_offset is past the end of the directory) {
    	*eofflag = TRUE;
        }
        return error;
    }

エラー

[EINVAL]
    ディレクトリ内の不正なオフセットから読込もうとしました。

[EIO]
    ディレクトリの読込み中に、読取りエラーが発生しました。

関連項目
vnode(9)

作者
このマニュアルページは Doug Rabson が書きました。