EN JA
GETDENTS(2)
GETDENTS(2) Linux Programmer's Manual GETDENTS(2)

名前

getdents -ディレクトリ・エントリを取得する

書式


int getdents(unsigned int fd , struct linux_dirent * dirp ,
unsigned int count );
 
: このシステムコールには glibc のラッパー関数は存在しない。「注意」の節を参照。

説明

これはあなたの関心を引くような関数ではない。 POSIX 準拠の C ライブラリインターフェースについては readdir(3) を見ること。このページは、カーネルシステムコールの生のインターフェースについて記載したものである。

getdents() システムコールは、オープン済みのファイルディスクリプタ fd で参照されるディレクトリから linux_dirent 構造体をいくつか読み出し、 dirp が指しているバッファに格納する。 count 引き数はそのバッファのサイズを示す。

linux_dirent 構造体は以下のように宣言されている:



struct linux_dirent {
unsigned long d_ino; /* Inode number */
unsigned long d_off; /* Offset to next linux_dirent */
unsigned short d_reclen; /* Length of this linux_dirent */
char d_name[]; /* Filename (null-terminated) */
/* length is actually (d_reclen - 2 -
offsetof(struct linux_dirent, d_name)) */
/*
char pad; // Zero padding byte
char d_type; // File type (only since Linux
// 2.6.4); offset is (d_reclen - 1)
*/


}

d_ino は inode 番号である。 d_off はディレクトリの先頭から次の linux_dirent の先頭までの距離である。 d_reclen はこの linux_dirent 全体のサイズである。 d_name はヌル(null)文字で終わるファイル名である。

 

d_type は、構造体の最後のバイトであり、ファイルタイプを示す。 d_type は以下の値の一つを取る ( <dirent.h> で定義されている)。

DT_BLK
ブロックデバイスである。
DT_CHR
キャラクタデバイスである。
DT_DIR
ディレクトリである。
DT_FIFO
名前付きパイプ (FIFO) である。
DT_LNK
シンボリックリンクである。
DT_REG
通常のファイルである。
DT_SOCK
UNIX ドメインソケットである。
DT_UNKNOWN
ファイルタイプが不明である。

d_type フィールドは Linux 2.6.4 から実装されている。これは linux_dirent 構造体のうち、以前はゼロで埋められていた空間に配置されている。従って、2.6.3 以前のカーネルでは、このフィールドにアクセスしようとすると常に値 0 ( DT_UNKNOWN) が返される。

現在のところ、 d_type でファイルタイプを返す機能が完全にサポートされているのは、いくつかのファイルシステムにおいてのみである (Btrfs, ext2, ext3, ext4 はサポートしている)。どのアプリケーションも、 DT_UNKNOWN が返された際に適切に処理できなければならない。

返り値

成功した場合は、読み込んだバイト数が返される。ディレクトリの終わりならば 0 が返される。エラーの場合は-1 を返され、 errno に適切な値が設定される。

エラー

EBADF
ファイルディスクリプタ fd が不正である。
EFAULT
引き数が呼び出したプロセスのアドレス空間外を指している。
EINVAL
結果用のバッファーが小さすぎる。
ENOENT
そのようなディレクトリは存在しない。
ENOTDIR
ファイルディスクリプタがディレクトリを参照していない。

準拠

SVr4.

注意

glibc はこのシステムコールに対するラッパー関数を提供していないので、 syscall(2) を使って呼び出すこと。 linux_dirent 構造体は自分で定義する必要がある。しかし、たいていはこのシステムコールではなく readdir(3) を使うべき場面のことが多い。
 
このシステムコールは readdir(2) を置き換えるものである。
 
元々の Linux の getdents() システムコールは、大きなファイルシステムと大きなファイルオフセットを扱うことができなかった。その結果、Linux 2.4 で getdents64() が追加された。 getdents64() では、 linux_dirent 構造体のフィールド d_inod_off でビット幅の大きなデータ型が使われている。

下記のプログラムは getdents() の使用例を示したものである。以下は、このプログラムを ext2 ディレクトリで実行した際に得られる出力の例である。
 


$ ./a.out /testfs/
--------------- nread=120 ---------------
i-node# file type d_reclen d_off d_name
2 directory 16 12 .
2 directory 16 24 ..
11 directory 24 44 lost+found
12 regular 16 56 a
228929 directory 16 68 sub
16353 directory 16 80 sub2
130817 directory 16 4096 sub3

プログラムのソース


#define _GNU_SOURCE
#include <dirent.h> /* Defines DT_* constants */
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>


#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)


struct linux_dirent {
long d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name[];
};


#define BUF_SIZE 1024


int
main(int argc, char *argv[])
{
int fd, nread;
char buf[BUF_SIZE];
struct linux_dirent *d;
int bpos;
char d_type;


fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
if (fd == -1)
handle_error("open");


for ( ; ; ) {
nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
if (nread == -1)
handle_error("getdents");


if (nread == 0)
break;


printf("--------------- nread=%d ---------------\n", nread);
printf("i-node# file type d_reclen d_off d_name\n");
for (bpos = 0; bpos < nread;) {
d = (struct linux_dirent *) (buf + bpos);
printf("%8ld ", d->d_ino);
d_type = *(buf + bpos + d->d_reclen - 1);
printf("%-10s ", (d_type == DT_REG) ? "regular" :
(d_type == DT_DIR) ? "directory" :
(d_type == DT_FIFO) ? "FIFO" :
(d_type == DT_SOCK) ? "socket" :
(d_type == DT_LNK) ? "symlink" :
(d_type == DT_BLK) ? "block dev" :
(d_type == DT_CHR) ? "char dev" : "???");
printf("%4d %10lld %s\n", d->d_reclen,
(long long) d->d_off, d->d_name);
bpos += d->d_reclen;
}
}


exit(EXIT_SUCCESS);
}

関連項目

readdir(2), readdir(3)

この文書について

この man ページは Linux man-pages プロジェクトのリリース 3.51 の一部である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
2012-08-03 Linux