1GETDENTS(2)                Linux Programmer's Manual               GETDENTS(2)
2
3
4

NAME

6       getdents, getdents64 - get directory entries
7

SYNOPSIS

9       #include <sys/syscall.h>      /* Definition of SYS_* constants */
10       #include <unistd.h>
11
12       long syscall(SYS_getdents, unsigned int fd, struct linux_dirent *dirp,
13                    unsigned int count);
14
15       #define _GNU_SOURCE           /* See feature_test_macros(7) */
16       #include <dirent.h>
17
18       ssize_t getdents64(int fd, void *dirp, size_t count);
19
20       Note:  glibc  provides no wrapper for getdents(), necessitating the use
21       of syscall(2).
22
23       Note: There is no definition  of  struct  linux_dirent  in  glibc;  see
24       NOTES.
25

DESCRIPTION

27       These are not the interfaces you are interested in.  Look at readdir(3)
28       for the POSIX-conforming C library interface.  This page documents  the
29       bare kernel system call interfaces.
30
31   getdents()
32       The  system  call getdents() reads several linux_dirent structures from
33       the directory referred to by the open file descriptor fd into the  buf‐
34       fer  pointed to by dirp.  The argument count specifies the size of that
35       buffer.
36
37       The linux_dirent structure is declared as follows:
38
39           struct linux_dirent {
40               unsigned long  d_ino;     /* Inode number */
41               unsigned long  d_off;     /* Offset to next linux_dirent */
42               unsigned short d_reclen;  /* Length of this linux_dirent */
43               char           d_name[];  /* Filename (null-terminated) */
44                                 /* length is actually (d_reclen - 2 -
45                                    offsetof(struct linux_dirent, d_name)) */
46               /*
47               char           pad;       // Zero padding byte
48               char           d_type;    // File type (only since Linux
49                                         // 2.6.4); offset is (d_reclen - 1)
50               */
51           }
52
53       d_ino is an inode number.  d_off is the distance from the start of  the
54       directory  to the start of the next linux_dirent.  d_reclen is the size
55       of this entire linux_dirent.  d_name is a null-terminated filename.
56
57       d_type is a byte at the end of the structure that  indicates  the  file
58       type.  It contains one of the following values (defined in <dirent.h>):
59
60       DT_BLK      This is a block device.
61
62       DT_CHR      This is a character device.
63
64       DT_DIR      This is a directory.
65
66       DT_FIFO     This is a named pipe (FIFO).
67
68       DT_LNK      This is a symbolic link.
69
70       DT_REG      This is a regular file.
71
72       DT_SOCK     This is a UNIX domain socket.
73
74       DT_UNKNOWN  The file type is unknown.
75
76       The d_type field is implemented since Linux 2.6.4.  It occupies a space
77       that was previously a zero-filled  padding  byte  in  the  linux_dirent
78       structure.   Thus,  on kernels up to and including 2.6.3, attempting to
79       access this field always provides the value 0 (DT_UNKNOWN).
80
81       Currently, only some filesystems (among them: Btrfs,  ext2,  ext3,  and
82       ext4) have full support for returning the file type in d_type.  All ap‐
83       plications must properly handle a return of DT_UNKNOWN.
84
85   getdents64()
86       The original Linux getdents() system call did not handle large filesys‐
87       tems  and  large  file  offsets.   Consequently,  Linux  2.4 added get‐
88       dents64(), with wider types for the d_ino and d_off fields.   In  addi‐
89       tion, getdents64() supports an explicit d_type field.
90
91       The getdents64() system call is like getdents(), except that its second
92       argument is a pointer to a buffer containing structures of the  follow‐
93       ing type:
94
95           struct linux_dirent64 {
96               ino64_t        d_ino;    /* 64-bit inode number */
97               off64_t        d_off;    /* 64-bit offset to next structure */
98               unsigned short d_reclen; /* Size of this dirent */
99               unsigned char  d_type;   /* File type */
100               char           d_name[]; /* Filename (null-terminated) */
101           };
102

RETURN VALUE

104       On success, the number of bytes read is returned.  On end of directory,
105       0 is returned.  On error, -1 is returned, and errno is set to  indicate
106       the error.
107

ERRORS

109       EBADF  Invalid file descriptor fd.
110
111       EFAULT Argument points outside the calling process's address space.
112
113       EINVAL Result buffer is too small.
114
115       ENOENT No such directory.
116
117       ENOTDIR
118              File descriptor does not refer to a directory.
119

CONFORMING TO

121       SVr4.
122

NOTES

124       Library  support  for  getdents64() was added in glibc 2.30; Glibc does
125       not provide a wrapper for getdents(); call getdents() (or  getdents64()
126       on  earlier  glibc  versions)  using syscall(2).  In that case you will
127       need to define the linux_dirent or linux_dirent64 structure yourself.
128
129       Probably, you want to use readdir(3) instead of these system calls.
130
131       These calls supersede readdir(2).
132

EXAMPLES

134       The program below demonstrates the use of  getdents().   The  following
135       output  shows an example of what we see when running this program on an
136       ext2 directory:
137
138           $ ./a.out /testfs/
139           --------------- nread=120 ---------------
140           inode#    file type  d_reclen  d_off   d_name
141                  2  directory    16         12  .
142                  2  directory    16         24  ..
143                 11  directory    24         44  lost+found
144                 12  regular      16         56  a
145             228929  directory    16         68  sub
146              16353  directory    16         80  sub2
147             130817  directory    16       4096  sub3
148
149   Program source
150
151       #define _GNU_SOURCE
152       #include <dirent.h>     /* Defines DT_* constants */
153       #include <fcntl.h>
154       #include <stdint.h>
155       #include <stdio.h>
156       #include <unistd.h>
157       #include <stdlib.h>
158       #include <sys/stat.h>
159       #include <sys/syscall.h>
160
161       #define handle_error(msg) \
162               do { perror(msg); exit(EXIT_FAILURE); } while (0)
163
164       struct linux_dirent {
165           unsigned long  d_ino;
166           off_t          d_off;
167           unsigned short d_reclen;
168           char           d_name[];
169       };
170
171       #define BUF_SIZE 1024
172
173       int
174       main(int argc, char *argv[])
175       {
176           int fd;
177           long nread;
178           char buf[BUF_SIZE];
179           struct linux_dirent *d;
180           char d_type;
181
182           fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
183           if (fd == -1)
184               handle_error("open");
185
186           for (;;) {
187               nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
188               if (nread == -1)
189                   handle_error("getdents");
190
191               if (nread == 0)
192                   break;
193
194               printf("--------------- nread=%d ---------------\n", nread);
195               printf("inode#    file type  d_reclen  d_off   d_name\n");
196               for (long bpos = 0; bpos < nread;) {
197                   d = (struct linux_dirent *) (buf + bpos);
198                   printf("%8ld  ", d->d_ino);
199                   d_type = *(buf + bpos + d->d_reclen - 1);
200                   printf("%-10s ", (d_type == DT_REG) ?  "regular" :
201                                    (d_type == DT_DIR) ?  "directory" :
202                                    (d_type == DT_FIFO) ? "FIFO" :
203                                    (d_type == DT_SOCK) ? "socket" :
204                                    (d_type == DT_LNK) ?  "symlink" :
205                                    (d_type == DT_BLK) ?  "block dev" :
206                                    (d_type == DT_CHR) ?  "char dev" : "???");
207                   printf("%4d %10jd  %s\n", d->d_reclen,
208                           (intmax_t) d->d_off, d->d_name);
209                   bpos += d->d_reclen;
210               }
211           }
212
213           exit(EXIT_SUCCESS);
214       }
215

SEE ALSO

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

COLOPHON

220       This page is part of release 5.13 of the Linux  man-pages  project.   A
221       description  of  the project, information about reporting bugs, and the
222       latest    version    of    this    page,    can     be     found     at
223       https://www.kernel.org/doc/man-pages/.
224
225
226
227Linux                             2021-03-22                       GETDENTS(2)
Impressum