Man page - getdents(2)

Packages contains this manual

Available languages:

en fr pl ja ru de

Manual

GETDENTS

名 前
書 式
説 明
getdents()
getdents64()
返 り 値
エ ラ ー
準 拠
注 意

プ ロ グ ラ ム の ソ ー ス
関 連 項 目
こ の 文 書 に つ い て

名 前

getdents, getdents64 - デ ィ レ ク ト リ エ ン ト リ ー を 取 得 す る

書 式

long getdents(unsigned int fd , struct linux_dirent * dirp ,
unsigned int
count );

#define _GNU_SOURCE /* feature_test_macros(7) 参 照 */
#include <dirent.h>

ssize_t getdents64(int fd , void * dirp , size_t count );

: getdents () の glibc の ラ ッ パ ー 関 数 は 存 在 し な い 。 「 注 意 」 の 節 を 参 照 。

説 明

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

getdents()

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

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

struct linux_dirent {
unsigned long d_ino; /* inode 番 号 */
unsigned long d_off; /* 次 の linux_dirent へ の オ フ セ ッ ト */
unsigned short d_reclen; /* こ の linux_dirent の 長 さ */
char d_name[]; /* (ヌ ル 終 端 さ れ た ) フ ァ イ ル 名 */
/* 実 際 の 長 さ は (d_reclen - 2 -
offsetof(struct linux_dirent, d_name)) */
/*
char pad; // 値 0 の パ デ ィ ン グ バ イ ト
char d_type; // フ ァ イ ル 種 別 (Linux 2.6.4 以 降 の み );
// オ フ セ ッ ト は (d_reclen - 1)
*/
}

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

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 が 返 さ れ た 際 に 適 切 に 処 理 で き な け れ ば な ら な い 。

getdents64()

元 々 の Linux の getdents () シ ス テ ム コ ー ル は 、 大 き な フ ァ イ ル シ ス テ ム と 大 き な フ ァ イ ル オ フ セ ッ ト を 扱 う こ と が で き な か っ た 。 そ の た め 、 Linux 2.4 で getdents64 () が 追 加 さ れ た 。 getdents64 () で は 、 d_ino d_off で ビ ッ ト 幅 の 大 き な デ ー タ 型 が 使 わ れ て い る 。 ま た 、 getdents64 () で は d_type フ ィ ー ル ド が 明 示 的 に サ ポ ー ト さ れ て い る 。

getdents64 () シ ス テ ム コ ー ル は getdents () と 似 て い る が 、 2 番 目 の 引 数 が 以 下 の 構 造 体 が 入 っ た バ ッ フ ァ へ の ポ イ ン タ ー で あ る 点 が 異 な る 。

struct linux_dirent64 {
ino64_t d_ino; /* 64 ビ ッ ト の inode 番 号 */
off64_t d_off; /* 次 の 構 造 体 へ の 64 ビ ッ ト の オ フ セ ッ ト */
unsigned short d_reclen; /* こ の dirent の 大 き さ */
unsigned char d_type; /* フ ァ イ ル 種 別 */
char d_name[]; /* (ヌ ル 終 端 さ れ た ) フ ァ イ ル 名 */
};

返 り 値

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

エ ラ ー

EBADF

フ ァ イ ル デ ィ ス ク リ プ タ ー fd が 不 正 で あ る 。

EFAULT

引 数 が 呼 び 出 し 元 プ ロ セ ス の ア ド レ ス 空 間 外 を 指 し て い る 。

EINVAL

結 果 用 の バ ッ フ ァ ー が 小 さ す ぎ る 。

ENOENT

そ の よ う な デ ィ レ ク ト リ は 存 在 し な い 。

ENOTDIR

フ ァ イ ル デ ィ ス ク リ プ タ ー が デ ィ レ ク ト リ を 参 照 し て い な い 。

準 拠

SVr4.

注 意

getdents64 () に 対 応 す る ラ イ ブ ラ リ の サ ポ ー ト は glibc 2.30 で 追 加 さ れ た 。 getdents () に 対 す る glibc ラ ッ パ ー 関 数 は 存 在 し な い 。 getdents () (も し く は glibc の 古 い バ ー ジ ョ ン で の getdents64 ()) を 呼 び 出 す に は 、 syscall (2) を 使 う 必 要 が あ る 。 そ の 場 合 、 構 造 体 linux_dirent linux_dirent64 を 自 分 で 定 義 す る 必 要 が あ る だ ろ う 。

お そ ら く 、 あ な た が 使 い た い の は 、 こ れ ら の シ ス テ ム コ ー ル で は な く readdir (3) の 方 で あ ろ う 。

こ れ ら の シ ス テ ム コ ー ル は readdir (2) を 置 き 換 え る も の で あ る 。

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

$ ./a.out /testfs/
--------------- nread=120 ---------------
inode# 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> /* DT_* 定 数 の 定 義 */
#include <fcntl.h>
#include <stdint.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 {
unsigned 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;
long nread;
char buf[BUF_SIZE];
struct linux_dirent *d;
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("inode# file type d_reclen d_off d_name\n");
for (long 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 %10jd %s\n", d->d_reclen,
(intmax_t) d->d_off, d->d_name);
bpos += d->d_reclen;
}
}

exit(EXIT_SUCCESS);
}

関 連 項 目

readdir (2), readdir (3), inode (7)

こ の 文 書 に つ い て

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