Provided by: manpages-ja-dev_0.5.0.0.20140515+dfsg-2_all bug

名前

       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 はヌル文字で終わるファ
       イル名である。

       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.65 の一部 である。プロジェクト
       の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。