[JM:02641] Re: [POST:DP] LDP man-pages getdents.2

アーカイブの一覧に戻る
Akihiro Motoki amoto****@gmail*****
2021年 7月 6日 (火) 22:57:42 JST


コメントを受けて更新した版を投稿します。

<STATUS>
stat: DP
ppkg: LDP man-pages
page: getdents.2
date: 2021/07/06
mail: amoto****@gmail*****
name: Akihiro Motoki
</STATUS>

.\"O .TH GETDENTS 2  2020-11-01 "Linux" "Linux Programmer's Manual"
.TH GETDENTS 2 2020\-11\-01 Linux "Linux Programmer's Manual"
.\"O ----------------------------------------
.\"O .SH NAME
.\"O getdents, getdents64 \- get directory entries
.SH 名前
getdents, getdents64 \- ディレクトリエントリーを取得する
.\"O ----------------------------------------
.\"O .SH SYNOPSIS
.\"O .nf
.\"O .BI "long getdents(unsigned int " fd ", struct linux_dirent *" dirp ,
.\"O .BI "             unsigned int " count );
.SH 書式
.nf
\fBlong getdents(unsigned int \fP\fIfd\fP\fB, struct linux_dirent
*\fP\fIdirp\fP\fB,\fP
\fB             unsigned int \fP\fIcount\fP\fB);\fP
.\"O ----------------------------------------
.\"O .PP
.\"O .BR "#define _GNU_SOURCE" "        /* See feature_test_macros(7) */"
.\"O .BR "#include <dirent.h>"
.PP
\fB#define _GNU_SOURCE\fP        /* feature_test_macros(7) 参照 */
\fB#include <dirent.h>\fP
.\"O ----------------------------------------
.\"O .PP
.\"O .BI "ssize_t getdents64(int " fd ", void *" dirp ", size_t " count );
.\"O .fi
.PP
\fBssize_t getdents64(int \fP\fIfd\fP\fB, void *\fP\fIdirp\fP\fB,
size_t \fP\fIcount\fP\fB);\fP
.fi
.\"O ----------------------------------------
.\"O .PP
.\"O .IR Note :
.\"O There is no glibc wrapper for
.\"O .BR getdents ();
.\"O see NOTES.
.PP
\fI注\fP: \fBgetdents\fP() の glibc のラッパー関数は存在しない。「注意」の節を参照。
.\"O ----------------------------------------
.\"O .SH DESCRIPTION
.\"O These are not the interfaces you are interested in.
.\"O Look at
.\"O .BR readdir (3)
.\"O for the POSIX-conforming C library interface.
.\"O This page documents the bare kernel system call interfaces.
.SH 説明
これらはあなたの関心を引くようなインターフェースではないだろう。 POSIX 準拠の C ライブラリインターフェースについては
\fBreaddir\fP(3) を参照のこと。このページは、カーネルシステムコールの生のインターフェースについて記載したものである。
.\"O ----------------------------------------
.\"O .SS getdents()
.\"O The system call
.\"O .BR getdents ()
.\"O reads several
.\"O .I linux_dirent
.\"O structures from the directory
.\"O referred to by the open file descriptor
.\"O .I fd
.\"O into the buffer pointed to by
.\"O .IR dirp .
.\"O The argument
.\"O .I count
.\"O specifies the size of that buffer.
.SS getdents()
\fBgetdents\fP()  システムコールは、オープン済みのファイルディスクリプター \fIfd\fP で参照されるディレクトリから
\fIlinux_dirent\fP 構造体をいくつか読み出し、 \fIdirp\fP が指しているバッファーに格納する。 \fIcount\fP
引き数はそのバッファーのサイズを示す。
.\"O ----------------------------------------
.\"O .PP
.\"O The
.\"O .I linux_dirent
.\"O structure is declared as follows:
.PP
\fIlinux_dirent\fP 構造体は以下のように宣言されている。
.\"O ----------------------------------------
.\"O .PP
.\"O .in +4n
.\"O .EX
.\"O struct linux_dirent {
.\"O     unsigned long  d_ino;     /* Inode number */
.\"O     unsigned long  d_off;     /* Offset to next \fIlinux_dirent\fP */
.\"O     unsigned short d_reclen;  /* Length of this \fIlinux_dirent\fP */
.\"O     char           d_name[];  /* Filename (null-terminated) */
.\"O                       /* length is actually (d_reclen \- 2 \-
.\"O                          offsetof(struct linux_dirent, d_name)) */
.\"O     /*
.\"O     char           pad;       // Zero padding byte
.\"O     char           d_type;    // File type (only since Linux
.\"O                               // 2.6.4); offset is (d_reclen \- 1)
.\"O     */
.\"O }
.\"O .EE
.\"O .in
.PP
.in +4n
.EX
struct linux_dirent {
    unsigned long  d_ino;     /* inode 番号 */
    unsigned long  d_off;     /* 次の \fIlinux_dirent\fP へのオフセット */
    unsigned short d_reclen;  /* この \fIlinux_dirent\fP の長さ */
    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)
    */
}
.EE
.in
.\"O ----------------------------------------
.\"O .PP
.\"O .I d_ino
.\"O is an inode number.
.\"O .I d_off
.\"O is the distance from the start of the directory to the start of the next
.\"O .IR linux_dirent .
.\"O .I d_reclen
.\"O is the size of this entire
.\"O .IR linux_dirent .
.\"O .I d_name
.\"O is a null-terminated filename.
.PP
\fId_ino\fP は inode 番号である。 \fId_off\fP はディレクトリの先頭から次の
\fIlinux_dirent\fP の先頭までの距離である。
\fId_reclen\fP はこの \fIlinux_dirent\fP 全体のサイズである。 \fId_name\fP はヌル文字で終わるファイル名である。
.\"O ----------------------------------------
.\"O .PP
.\"O .I d_type
.\"O is a byte at the end of the structure that indicates the file type.
.\"O It contains one of the following values (defined in
.\"O .IR <dirent.h> ):
.PP
\fId_type\fP は、構造体の最後のバイトであり、ファイルタイプを示す。 \fId_type\fP は以下の値のいずれか一つを取る
(\fI<dirent.h>\fP で定義されている)。
.\"O ----------------------------------------
.\"O .TP 12
.\"O .B DT_BLK
.\"O This is a block device.
.TP  12
\fBDT_BLK\fP
ブロックデバイスである。
.\"O ----------------------------------------
.\"O .TP
.\"O .B DT_CHR
.\"O This is a character device.
.TP
\fBDT_CHR\fP
キャラクターデバイスである。
.\"O ----------------------------------------
.\"O .TP
.\"O .B DT_DIR
.\"O This is a directory.
.TP
\fBDT_DIR\fP
ディレクトリである。
.\"O ----------------------------------------
.\"O .TP
.\"O .B DT_FIFO
.\"O This is a named pipe (FIFO).
.TP
\fBDT_FIFO\fP
名前付きパイプ (FIFO) である。
.\"O ----------------------------------------
.\"O .TP
.\"O .B DT_LNK
.\"O This is a symbolic link.
.TP
\fBDT_LNK\fP
シンボリックリンクである。
.\"O ----------------------------------------
.\"O .TP
.\"O .B DT_REG
.\"O This is a regular file.
.TP
\fBDT_REG\fP
通常のファイルである。
.\"O ----------------------------------------
.\"O .TP
.\"O .B DT_SOCK
.\"O This is a UNIX domain socket.
.TP
\fBDT_SOCK\fP
UNIX ドメインソケットである。
.\"O ----------------------------------------
.\"O .TP
.\"O .B DT_UNKNOWN
.\"O The file type is unknown.
.TP
\fBDT_UNKNOWN\fP
ファイルタイプが不明。
.\"O ----------------------------------------
.\"O .PP
.\"O The
.\"O .I d_type
.\"O field is implemented since Linux 2.6.4.
.\"O It occupies a space that was previously a zero-filled padding byte in the
.\"O .IR linux_dirent
.\"O structure.
.\"O Thus, on kernels up to and including 2.6.3,
.\"O attempting to access this field always provides the value 0
.\"O .RB ( DT_UNKNOWN ).
.PP
\fId_type\fP フィールドは Linux 2.6.4 以降で実装されている。 このフィールドは、 \fIlinux_dirent\fP
構造体の中で以前はゼロで埋められていた空間に配置されている。 したがって、2.6.3 以前のカーネルでは、このフィールドにアクセスしようとすると 常に値
0 (\fBDT_UNKNOWN\fP) が返される。
.\"O ----------------------------------------
.\"O .PP
.\"O Currently,
.\"O only some filesystems (among them: Btrfs, ext2, ext3, and ext4)
.\"O have full support for returning the file type in
.\"O .IR d_type .
.\"O All applications must properly handle a return of
.\"O .BR DT_UNKNOWN .
.PP
現在のところ、 \fId_type\fP でファイルタイプを返す機能が完全にサポートされているのは、 いくつかのファイルシステムにおいてのみである
(Btrfs, ext2, ext3, ext4 はサポートしている)。 どのアプリケーションも \fBDT_UNKNOWN\fP
が返された際に適切に処理できなければならない。
.\"O ----------------------------------------
.\"O .SS getdents64()
.\"O The original Linux
.\"O .BR getdents ()
.\"O system call did not handle large filesystems and large file offsets.
.\"O Consequently, Linux 2.4 added
.\"O .BR getdents64 (),
.\"O with wider types for the
.\"O .I d_ino
.\"O and
.\"O .I d_off
.\"O fields.
.\"O In addition,
.\"O .BR getdents64 ()
.\"O supports an explicit
.\"O .I d_type
.\"O field.
.SS getdents64()
元々の Linux の \fBgetdents\fP()
システムコールは、大きなファイルシステムと大きなファイルオフセットを扱うことができなかった。そのため、Linux 2.4 で
\fBgetdents64\fP() が追加された。 \fBgetdents64\fP() では、 \fId_ino\fP と \fId_off\fP
でビット幅の大きなデータ型が使われている。また、 \fBgetdents64\fP() では \fId_type\fP フィールドが明示的にサポートされている。
.\"O ----------------------------------------
.\"O .PP
.\"O The
.\"O .BR getdents64 ()
.\"O system call is like
.\"O .BR getdents (),
.\"O except that its second argument is a pointer to a buffer containing
.\"O structures of the following type:
.PP
\fBgetdents64\fP() システムコールは \fBgetdents\fP() と似ているが、 2
番目の引き数が以下の構造体が入ったバッファへのポインターである点が異なる。
.\"O ----------------------------------------
.\"O .PP
.\"O .in +4n
.\"O .EX
.\"O struct linux_dirent64 {
.\"O     ino64_t        d_ino;    /* 64-bit inode number */
.\"O     off64_t        d_off;    /* 64-bit offset to next structure */
.\"O     unsigned short d_reclen; /* Size of this dirent */
.\"O     unsigned char  d_type;   /* File type */
.\"O     char           d_name[]; /* Filename (null-terminated) */
.\"O };
.\"O .EE
.\"O .in
.PP
.in +4n
.EX
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[]; /* (ヌル終端された) ファイル名 */
};
.EE
.in
.\"O ----------------------------------------
.\"O .SH RETURN VALUE
.\"O On success, the number of bytes read is returned.
.\"O On end of directory, 0 is returned.
.\"O On error, \-1 is returned, and
.\"O .I errno
.\"O is set appropriately.
.SH 返り値
成功した場合は、読み込んだバイト数が返される。 ディレクトリの終わりならば 0 が返される。 エラーの場合は \-1 が返され、 \fIerrno\fP
に適切な値が設定される。
.\"O ----------------------------------------
.\"O .SH ERRORS
.SH エラー
.\"O ----------------------------------------
.\"O .TP
.\"O .B EBADF
.\"O Invalid file descriptor
.\"O .IR fd .
.TP
\fBEBADF\fP
ファイルディスクリプター \fIfd\fP が不正である。
.\"O ----------------------------------------
.\"O .TP
.\"O .B EFAULT
.\"O Argument points outside the calling process's address space.
.TP
\fBEFAULT\fP
引き数が呼び出し元プロセスのアドレス空間外を指している。
.\"O ----------------------------------------
.\"O .TP
.\"O .B EINVAL
.\"O Result buffer is too small.
.TP
\fBEINVAL\fP
結果用のバッファーが小さすぎる。
.\"O ----------------------------------------
.\"O .TP
.\"O .B ENOENT
.\"O No such directory.
.TP
\fBENOENT\fP
そのようなディレクトリは存在しない。
.\"O ----------------------------------------
.\"O .TP
.\"O .B ENOTDIR
.\"O File descriptor does not refer to a directory.
.TP
\fBENOTDIR\fP
ファイルディスクリプターがディレクトリを参照していない。
.\"O ----------------------------------------
.\"O .SH CONFORMING TO
.\"O SVr4.
.SH 準拠
SVr4.
.\"O ----------------------------------------
.\"O .SH NOTES
.\"O Library support for
.\"O .BR getdents64 ()
.\"O was added in glibc 2.30;
.\"O there is no glibc wrapper for
.\"O .BR getdents ().
.\"O Calling
.\"O .BR getdents ()
.\"O (or
.\"O .BR getdents64 ()
.\"O on earlier glibc versions) requires the use of
.\"O .BR syscall (2).
.\"O In that case you will need to define the
.\"O .I linux_dirent
.\"O or
.\"O .I linux_dirent64
.\"O structure yourself.
.SH 注意
\fBgetdents64\fP() に対応するライブラリのサポートは glibc 2.30 で追加された。
\fBgetdents\fP() に対する glibc
ラッパー関数は存在しない。 \fBgetdents\fP() (もしくは glibc の古いバージョンでの
\fBgetdents64\fP()) を呼び出すには、
\fBsyscall\fP(2) を使う必要がある。その場合、構造体 \fIlinux_dirent\fP や \fIlinux_dirent64\fP
を自分で定義する必要があるだろう。
.\"O ----------------------------------------
.\"O .PP
.\"O Probably, you want to use
.\"O .BR readdir (3)
.\"O instead of these system calls.
.PP
おそらく、あなたが使いたいのは、これらのシステムコールではなく \fBreaddir\fP(3) の方であろう。
.\"O ----------------------------------------
.\"O .PP
.\"O These calls supersede
.\"O .BR readdir (2).
.PP
これらのシステムコールは \fBreaddir\fP(2)  を置き換えるものである。
.\"O ----------------------------------------
.\"O .SH EXAMPLES
.\"O The program below demonstrates the use of
.\"O .BR getdents ().
.\"O The following output shows an example of what we see when running this
.\"O program on an ext2 directory:
.SH 例
下記のプログラムは \fBgetdents\fP()  の使用例を示したものである。 以下は、このプログラムを ext2 ディレクトリで実行した際に得られる
出力の例である。
.\"O ----------------------------------------
.\"O .PP
.\"O .in +4n
.\"O .EX
.\"O .RB "$" " ./a.out /testfs/"
.\"O --------------- nread=120 ---------------
.\"O inode#    file type  d_reclen  d_off   d_name
.\"O        2  directory    16         12  .
.\"O        2  directory    16         24  ..
.\"O       11  directory    24         44  lost+found
.\"O       12  regular      16         56  a
.\"O   228929  directory    16         68  sub
.\"O    16353  directory    16         80  sub2
.\"O   130817  directory    16       4096  sub3
.\"O .EE
.\"O .in
.PP
.in +4n
.EX
$\fB ./a.out /testfs/\fP
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- 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
.EE
.in
.\"O ----------------------------------------
.\"O .SS Program source
.\"O \&
.\"O .EX
.\"O #define _GNU_SOURCE
.\"O #include <dirent.h>     /* Defines DT_* constants */
.\"O #include <fcntl.h>
.\"O #include <stdint.h>
.\"O #include <stdio.h>
.\"O #include <unistd.h>
.\"O #include <stdlib.h>
.\"O #include <sys/stat.h>
.\"O #include <sys/syscall.h>
.SS プログラムのソース
\&
.EX
#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>
.\"O ----------------------------------------
.\"O
.\"O #define handle_error(msg) \e
.\"O         do { perror(msg); exit(EXIT_FAILURE); } while (0)

#define handle_error(msg) \e
        do { perror(msg); exit(EXIT_FAILURE); } while (0)
.\"O ----------------------------------------
.\"O
.\"O struct linux_dirent {
.\"O     unsigned long  d_ino;
.\"O     off_t          d_off;
.\"O     unsigned short d_reclen;
.\"O     char           d_name[];
.\"O };

struct linux_dirent {
    unsigned long  d_ino;
    off_t          d_off;
    unsigned short d_reclen;
    char           d_name[];
};
.\"O ----------------------------------------
.\"O
.\"O #define BUF_SIZE 1024

#define BUF_SIZE 1024
.\"O ----------------------------------------
.\"O
.\"O int
.\"O main(int argc, char *argv[])
.\"O {
.\"O     int fd;
.\"O     long nread;
.\"O     char buf[BUF_SIZE];
.\"O     struct linux_dirent *d;
.\"O     char d_type;

int
main(int argc, char *argv[])
{
    int fd;
    long nread;
    char buf[BUF_SIZE];
    struct linux_dirent *d;
    char d_type;
.\"O ----------------------------------------
.\"O
.\"O     fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
.\"O     if (fd == \-1)
.\"O         handle_error("open");

    fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
    if (fd == \-1)
        handle_error("open");
.\"O ----------------------------------------
.\"O
.\"O     for (;;) {
.\"O         nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
.\"O         if (nread == \-1)
.\"O             handle_error("getdents");

    for (;;) {
        nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
        if (nread == \-1)
            handle_error("getdents");
.\"O ----------------------------------------
.\"O
.\"O         if (nread == 0)
.\"O             break;

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

        printf("\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- nread=%d
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\en", nread);
        printf("inode#    file type  d_reclen  d_off   d_name\en");
        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\en", d\->d_reclen,
                    (intmax_t) d\->d_off, d\->d_name);
            bpos += d\->d_reclen;
        }
    }
.\"O ----------------------------------------
.\"O
.\"O     exit(EXIT_SUCCESS);
.\"O }
.\"O .EE

    exit(EXIT_SUCCESS);
}
.EE
.\"O ----------------------------------------
.\"O .SH SEE ALSO
.\"O .BR readdir (2),
.\"O .BR readdir (3),
.\"O .BR inode (7)
.SH 関連項目
\fBreaddir\fP(2), \fBreaddir\fP(3), \fBinode\fP(7)
.\"O ----------------------------------------
.\"O .SH COLOPHON
.\"O This page is part of release 5.10 of the Linux
.\"O .I man-pages
.\"O project.
.\"O A description of the project,
.\"O information about reporting bugs,
.\"O and the latest version of this page,
.\"O can be found at
.\"O \%https://www.kernel.org/doc/man\-pages/.
.SH この文書について
この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は
\%https://www.kernel.org/doc/man\-pages/ に書かれている。
.\"O ----------------------------------------


linuxjm-discuss メーリングリストの案内
アーカイブの一覧に戻る