Changes.old: Add missing entry in 5.13 changelog
[man-pages.git] / man2 / getdents.2
blob8201c331028ac7a62f3e1b67cb388574207bdcb6
1 .\" Copyright (C) 1995 Andries Brouwer (aeb@cwi.nl)
2 .\" and Copyright 2008, 2015 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\"
4 .\" %%%LICENSE_START(VERBATIM)
5 .\" Permission is granted to make and distribute verbatim copies of this
6 .\" manual provided the copyright notice and this permission notice are
7 .\" preserved on all copies.
8 .\"
9 .\" Permission is granted to copy and distribute modified versions of this
10 .\" manual under the conditions for verbatim copying, provided that the
11 .\" entire resulting derived work is distributed under the terms of a
12 .\" permission notice identical to this one.
13 .\"
14 .\" Since the Linux kernel and libraries are constantly changing, this
15 .\" manual page may be incorrect or out-of-date.  The author(s) assume no
16 .\" responsibility for errors or omissions, or for damages resulting from
17 .\" the use of the information contained herein.  The author(s) may not
18 .\" have taken the same level of care in the production of this manual,
19 .\" which is licensed free of charge, as they might when working
20 .\" professionally.
21 .\"
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
24 .\" %%%LICENSE_END
25 .\"
26 .\" Written 11 June 1995 by Andries Brouwer <aeb@cwi.nl>
27 .\" Modified 22 July 1995 by Michael Chastain <mec@duracef.shout.net>:
28 .\"   Derived from 'readdir.2'.
29 .\" Modified Tue Oct 22 08:11:14 EDT 1996 by Eric S. Raymond <esr@thyrsus.com>
30 .\"
31 .TH GETDENTS 2  2021-03-22 "Linux" "Linux Programmer's Manual"
32 .SH NAME
33 getdents, getdents64 \- get directory entries
34 .SH SYNOPSIS
35 .nf
36 .BR "#include <sys/syscall.h>" "      /* Definition of " SYS_* " constants */"
37 .B #include <unistd.h>
38 .PP
39 .BI "long syscall(SYS_getdents, unsigned int " fd \
40 ", struct linux_dirent *" dirp ,
41 .BI "             unsigned int " count );
42 .PP
43 .BR "#define _GNU_SOURCE" "           /* See feature_test_macros(7) */"
44 .BR "#include <dirent.h>"
45 .PP
46 .BI "ssize_t getdents64(int " fd ", void *" dirp ", size_t " count );
47 .fi
48 .PP
49 .IR Note :
50 glibc provides no wrapper for
51 .BR getdents (),
52 necessitating the use of
53 .BR syscall (2).
54 .PP
55 .IR Note :
56 There is no definition of
57 .I struct linux_dirent
58 in glibc; see NOTES.
59 .SH DESCRIPTION
60 These are not the interfaces you are interested in.
61 Look at
62 .BR readdir (3)
63 for the POSIX-conforming C library interface.
64 This page documents the bare kernel system call interfaces.
65 .SS getdents()
66 The system call
67 .BR getdents ()
68 reads several
69 .I linux_dirent
70 structures from the directory
71 referred to by the open file descriptor
72 .I fd
73 into the buffer pointed to by
74 .IR dirp .
75 The argument
76 .I count
77 specifies the size of that buffer.
78 .PP
79 The
80 .I linux_dirent
81 structure is declared as follows:
82 .PP
83 .in +4n
84 .EX
85 struct linux_dirent {
86     unsigned long  d_ino;     /* Inode number */
87     unsigned long  d_off;     /* Offset to next \fIlinux_dirent\fP */
88     unsigned short d_reclen;  /* Length of this \fIlinux_dirent\fP */
89     char           d_name[];  /* Filename (null\-terminated) */
90                       /* length is actually (d_reclen \- 2 \-
91                          offsetof(struct linux_dirent, d_name)) */
92     /*
93     char           pad;       // Zero padding byte
94     char           d_type;    // File type (only since Linux
95                               // 2.6.4); offset is (d_reclen \- 1)
96     */
98 .EE
99 .in
101 .I d_ino
102 is an inode number.
103 .I d_off
104 is the distance from the start of the directory to the start of the next
105 .IR linux_dirent .
106 .I d_reclen
107 is the size of this entire
108 .IR linux_dirent .
109 .I d_name
110 is a null-terminated filename.
112 .I d_type
113 is a byte at the end of the structure that indicates the file type.
114 It contains one of the following values (defined in
115 .IR <dirent.h> ):
116 .TP 12
117 .B DT_BLK
118 This is a block device.
120 .B DT_CHR
121 This is a character device.
123 .B DT_DIR
124 This is a directory.
126 .B DT_FIFO
127 This is a named pipe (FIFO).
129 .B DT_LNK
130 This is a symbolic link.
132 .B DT_REG
133 This is a regular file.
135 .B DT_SOCK
136 This is a UNIX domain socket.
138 .B DT_UNKNOWN
139 The file type is unknown.
142 .I d_type
143 field is implemented since Linux 2.6.4.
144 It occupies a space that was previously a zero-filled padding byte in the
145 .IR linux_dirent
146 structure.
147 Thus, on kernels up to and including 2.6.3,
148 attempting to access this field always provides the value 0
149 .RB ( DT_UNKNOWN ).
151 Currently,
152 .\" kernel 2.6.27
153 .\" The same sentence is in readdir.2
154 only some filesystems (among them: Btrfs, ext2, ext3, and ext4)
155 have full support for returning the file type in
156 .IR d_type .
157 All applications must properly handle a return of
158 .BR DT_UNKNOWN .
159 .SS getdents64()
160 The original Linux
161 .BR getdents ()
162 system call did not handle large filesystems and large file offsets.
163 Consequently, Linux 2.4 added
164 .BR getdents64 (),
165 with wider types for the
166 .I d_ino
168 .I d_off
169 fields.
170 In addition,
171 .BR getdents64 ()
172 supports an explicit
173 .I d_type
174 field.
177 .BR getdents64 ()
178 system call is like
179 .BR getdents (),
180 except that its second argument is a pointer to a buffer containing
181 structures of the following type:
183 .in +4n
185 struct linux_dirent64 {
186     ino64_t        d_ino;    /* 64\-bit inode number */
187     off64_t        d_off;    /* 64\-bit offset to next structure */
188     unsigned short d_reclen; /* Size of this dirent */
189     unsigned char  d_type;   /* File type */
190     char           d_name[]; /* Filename (null\-terminated) */
194 .SH RETURN VALUE
195 On success, the number of bytes read is returned.
196 On end of directory, 0 is returned.
197 On error, \-1 is returned, and
198 .I errno
199 is set to indicate the error.
200 .SH ERRORS
202 .B EBADF
203 Invalid file descriptor
204 .IR fd .
206 .B EFAULT
207 Argument points outside the calling process's address space.
209 .B EINVAL
210 Result buffer is too small.
212 .B ENOENT
213 No such directory.
215 .B ENOTDIR
216 File descriptor does not refer to a directory.
217 .SH CONFORMING TO
218 SVr4.
219 .\" SVr4 documents additional ENOLINK, EIO error conditions.
220 .SH NOTES
221 Library support for
222 .BR getdents64 ()
223 was added in glibc 2.30;
224 Glibc does not provide a wrapper for
225 .BR getdents ();
226 call
227 .BR getdents ()
229 .BR getdents64 ()
230 on earlier glibc versions) using
231 .BR syscall (2).
232 In that case you will need to define the
233 .I linux_dirent
235 .I linux_dirent64
236 structure yourself.
238 Probably, you want to use
239 .BR readdir (3)
240 instead of these system calls.
242 These calls supersede
243 .BR readdir (2).
244 .SH EXAMPLES
245 .\" FIXME The example program needs to be revised, since it uses the older
246 .\" getdents() system call and the structure with smaller field widths.
247 The program below demonstrates the use of
248 .BR getdents ().
249 The following output shows an example of what we see when running this
250 program on an ext2 directory:
252 .in +4n
254 .RB "$" " ./a.out /testfs/"
255 -\-\-\-\-\-\-\-\-\-\-\-\-\-\- nread=120 \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
256 inode#    file type  d_reclen  d_off   d_name
257        2  directory    16         12  .
258        2  directory    16         24  ..
259       11  directory    24         44  lost+found
260       12  regular      16         56  a
261   228929  directory    16         68  sub
262    16353  directory    16         80  sub2
263   130817  directory    16       4096  sub3
266 .SS Program source
269 #define _GNU_SOURCE
270 #include <dirent.h>     /* Defines DT_* constants */
271 #include <fcntl.h>
272 #include <stdint.h>
273 #include <stdio.h>
274 #include <unistd.h>
275 #include <stdlib.h>
276 #include <sys/stat.h>
277 #include <sys/syscall.h>
279 #define handle_error(msg) \e
280         do { perror(msg); exit(EXIT_FAILURE); } while (0)
282 struct linux_dirent {
283     unsigned long  d_ino;
284     off_t          d_off;
285     unsigned short d_reclen;
286     char           d_name[];
289 #define BUF_SIZE 1024
292 main(int argc, char *argv[])
294     int fd;
295     long nread;
296     char buf[BUF_SIZE];
297     struct linux_dirent *d;
298     char d_type;
300     fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
301     if (fd == \-1)
302         handle_error("open");
304     for (;;) {
305         nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
306         if (nread == \-1)
307             handle_error("getdents");
309         if (nread == 0)
310             break;
312         printf("\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- nread=%d \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\en", nread);
313         printf("inode#    file type  d_reclen  d_off   d_name\en");
314         for (long bpos = 0; bpos < nread;) {
315             d = (struct linux_dirent *) (buf + bpos);
316             printf("%8ld  ", d\->d_ino);
317             d_type = *(buf + bpos + d\->d_reclen \- 1);
318             printf("%\-10s ", (d_type == DT_REG) ?  "regular" :
319                              (d_type == DT_DIR) ?  "directory" :
320                              (d_type == DT_FIFO) ? "FIFO" :
321                              (d_type == DT_SOCK) ? "socket" :
322                              (d_type == DT_LNK) ?  "symlink" :
323                              (d_type == DT_BLK) ?  "block dev" :
324                              (d_type == DT_CHR) ?  "char dev" : "???");
325             printf("%4d %10jd  %s\en", d\->d_reclen,
326                     (intmax_t) d\->d_off, d\->d_name);
327             bpos += d\->d_reclen;
328         }
329     }
331     exit(EXIT_SUCCESS);
334 .SH SEE ALSO
335 .BR readdir (2),
336 .BR readdir (3),
337 .BR inode (7)