Changes.old: tfix
[man-pages.git] / man2 / getdents.2
blob1e630f9e210b606e7420a9f3936d779da1e638b0
1 .\" Copyright (C) 1995 Andries Brouwer (aeb@cwi.nl)
2 .\" and Copyright 2008, 2015 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\"
4 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
5 .\"
6 .\" Written 11 June 1995 by Andries Brouwer <aeb@cwi.nl>
7 .\" Modified 22 July 1995 by Michael Chastain <mec@duracef.shout.net>:
8 .\"   Derived from 'readdir.2'.
9 .\" Modified Tue Oct 22 08:11:14 EDT 1996 by Eric S. Raymond <esr@thyrsus.com>
10 .\"
11 .TH getdents 2 (date) "Linux man-pages (unreleased)"
12 .SH NAME
13 getdents, getdents64 \- get directory entries
14 .SH LIBRARY
15 Standard C library
16 .RI ( libc ", " \-lc )
17 .SH SYNOPSIS
18 .nf
19 .BR "#include <sys/syscall.h>" "      /* Definition of " SYS_* " constants */"
20 .B #include <unistd.h>
22 .BI "long syscall(SYS_getdents, unsigned int " fd \
23 ", struct linux_dirent *" dirp ,
24 .BI "             unsigned int " count );
26 .BR "#define _GNU_SOURCE" "           /* See feature_test_macros(7) */"
27 .B #include <dirent.h>
29 .BI "ssize_t getdents64(int " fd ", void " dirp [. count "], size_t " count );
30 .fi
32 .IR Note :
33 glibc provides no wrapper for
34 .BR getdents (),
35 necessitating the use of
36 .BR syscall (2).
38 .IR Note :
39 There is no definition of
40 .I struct linux_dirent
41 in glibc; see NOTES.
42 .SH DESCRIPTION
43 These are not the interfaces you are interested in.
44 Look at
45 .BR readdir (3)
46 for the POSIX-conforming C library interface.
47 This page documents the bare kernel system call interfaces.
48 .SS getdents()
49 The system call
50 .BR getdents ()
51 reads several
52 .I linux_dirent
53 structures from the directory
54 referred to by the open file descriptor
55 .I fd
56 into the buffer pointed to by
57 .IR dirp .
58 The argument
59 .I count
60 specifies the size of that buffer.
62 The
63 .I linux_dirent
64 structure is declared as follows:
66 .in +4n
67 .EX
68 struct linux_dirent {
69     unsigned long  d_ino;     /* Inode number */
70     unsigned long  d_off;     /* Not an offset; see below */
71     unsigned short d_reclen;  /* Length of this \fIlinux_dirent\fP */
72     char           d_name[];  /* Filename (null\-terminated) */
73                       /* length is actually (d_reclen \- 2 \-
74                          offsetof(struct linux_dirent, d_name)) */
75     /*
76     char           pad;       // Zero padding byte
77     char           d_type;    // File type (only since Linux
78                               // 2.6.4); offset is (d_reclen \- 1)
79     */
81 .EE
82 .in
84 .I d_ino
85 is an inode number.
86 .I d_off
87 is a filesystem-specific value with no specific meaning to user space,
88 though on older filesystems it used to be
89 the distance from the start of the directory to the start of the next
90 .IR linux_dirent ;
91 see
92 .BR readdir (3) .
93 .I d_reclen
94 is the size of this entire
95 .IR linux_dirent .
96 .I d_name
97 is a null-terminated filename.
99 .I d_type
100 is a byte at the end of the structure that indicates the file type.
101 It contains one of the following values (defined in
102 .IR <dirent.h> ):
103 .TP 12
104 .B DT_BLK
105 This is a block device.
107 .B DT_CHR
108 This is a character device.
110 .B DT_DIR
111 This is a directory.
113 .B DT_FIFO
114 This is a named pipe (FIFO).
116 .B DT_LNK
117 This is a symbolic link.
119 .B DT_REG
120 This is a regular file.
122 .B DT_SOCK
123 This is a UNIX domain socket.
125 .B DT_UNKNOWN
126 The file type is unknown.
129 .I d_type
130 field is implemented since Linux 2.6.4.
131 It occupies a space that was previously a zero-filled padding byte in the
132 .I linux_dirent
133 structure.
134 Thus, on kernels up to and including Linux 2.6.3,
135 attempting to access this field always provides the value 0
136 .RB ( DT_UNKNOWN ).
138 Currently,
139 .\" kernel 2.6.27
140 .\" The same sentence is in readdir.2
141 only some filesystems (among them: Btrfs, ext2, ext3, and ext4)
142 have full support for returning the file type in
143 .IR d_type .
144 All applications must properly handle a return of
145 .BR DT_UNKNOWN .
146 .SS getdents64()
147 The original Linux
148 .BR getdents ()
149 system call did not handle large filesystems and large file offsets.
150 Consequently, Linux 2.4 added
151 .BR getdents64 (),
152 with wider types for the
153 .I d_ino
155 .I d_off
156 fields.
157 In addition,
158 .BR getdents64 ()
159 supports an explicit
160 .I d_type
161 field.
164 .BR getdents64 ()
165 system call is like
166 .BR getdents (),
167 except that its second argument is a pointer to a buffer containing
168 structures of the following type:
170 .in +4n
172 struct linux_dirent64 {
173     ino64_t        d_ino;    /* 64\-bit inode number */
174     off64_t        d_off;    /* Not an offset; see getdents() */
175     unsigned short d_reclen; /* Size of this dirent */
176     unsigned char  d_type;   /* File type */
177     char           d_name[]; /* Filename (null\-terminated) */
181 .SH RETURN VALUE
182 On success, the number of bytes read is returned.
183 On end of directory, 0 is returned.
184 On error, \-1 is returned, and
185 .I errno
186 is set to indicate the error.
187 .SH ERRORS
189 .B EBADF
190 Invalid file descriptor
191 .IR fd .
193 .B EFAULT
194 Argument points outside the calling process's address space.
196 .B EINVAL
197 Result buffer is too small.
199 .B ENOENT
200 No such directory.
202 .B ENOTDIR
203 File descriptor does not refer to a directory.
204 .SH STANDARDS
205 None.
206 .SH HISTORY
207 SVr4.
208 .\" SVr4 documents additional ENOLINK, EIO error conditions.
210 .BR getdents64 ()
211 glibc 2.30.
212 .SH NOTES
213 glibc does not provide a wrapper for
214 .BR getdents ();
215 call
216 .BR getdents ()
217 using
218 .BR syscall (2).
219 In that case you will need to define the
220 .I linux_dirent
222 .I linux_dirent64
223 structure yourself.
225 Probably, you want to use
226 .BR readdir (3)
227 instead of these system calls.
229 These calls supersede
230 .BR readdir (2).
231 .SH EXAMPLES
232 .\" FIXME The example program needs to be revised, since it uses the older
233 .\" getdents() system call and the structure with smaller field widths.
234 The program below demonstrates the use of
235 .BR getdents ().
236 The following output shows an example of what we see when running this
237 program on an ext2 directory:
239 .in +4n
241 .RB "$" " ./a.out /testfs/"
242 -\-\-\-\-\-\-\-\-\-\-\-\-\-\- nread=120 \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
243 inode#    file type  d_reclen  d_off   d_name
244        2  directory    16         12  .
245        2  directory    16         24  ..
246       11  directory    24         44  lost+found
247       12  regular      16         56  a
248   228929  directory    16         68  sub
249    16353  directory    16         80  sub2
250   130817  directory    16       4096  sub3
253 .SS Program source
255 .\" SRC BEGIN (getdents.c)
257 #define _GNU_SOURCE
258 #include <dirent.h>     /* Defines DT_* constants */
259 #include <err.h>
260 #include <fcntl.h>
261 #include <stdint.h>
262 #include <stdio.h>
263 #include <stdlib.h>
264 #include <sys/syscall.h>
265 #include <unistd.h>
267 struct linux_dirent {
268     unsigned long  d_ino;
269     off_t          d_off;
270     unsigned short d_reclen;
271     char           d_name[];
274 #define BUF_SIZE 1024
277 main(int argc, char *argv[])
279     int                  fd;
280     char                 d_type;
281     char                 buf[BUF_SIZE];
282     long                 nread;
283     struct linux_dirent  *d;
285     fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
286     if (fd == \-1)
287         err(EXIT_FAILURE, "open");
289     for (;;) {
290         nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
291         if (nread == \-1)
292             err(EXIT_FAILURE, "getdents");
294         if (nread == 0)
295             break;
297         printf("\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- nread=%ld \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\en", nread);
298         printf("inode#    file type  d_reclen  d_off   d_name\en");
299         for (size_t bpos = 0; bpos < nread;) {
300             d = (struct linux_dirent *) (buf + bpos);
301             printf("%8lu  ", d\->d_ino);
302             d_type = *(buf + bpos + d\->d_reclen \- 1);
303             printf("%\-10s ", (d_type == DT_REG) ?  "regular" :
304                              (d_type == DT_DIR) ?  "directory" :
305                              (d_type == DT_FIFO) ? "FIFO" :
306                              (d_type == DT_SOCK) ? "socket" :
307                              (d_type == DT_LNK) ?  "symlink" :
308                              (d_type == DT_BLK) ?  "block dev" :
309                              (d_type == DT_CHR) ?  "char dev" : "???");
310             printf("%4d %10jd  %s\en", d\->d_reclen,
311                    (intmax_t) d\->d_off, d\->d_name);
312             bpos += d\->d_reclen;
313         }
314     }
316     exit(EXIT_SUCCESS);
319 .\" SRC END
320 .SH SEE ALSO
321 .BR readdir (2),
322 .BR readdir (3),
323 .BR inode (7)