]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man2/getdents.2
Many pages: Fix style issues reported by `make lint-groff`
[thirdparty/man-pages.git] / man2 / getdents.2
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 2021-03-22 "Linux" "Linux Programmer's Manual"
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>
21 .PP
22 .BI "long syscall(SYS_getdents, unsigned int " fd \
23 ", struct linux_dirent *" dirp ,
24 .BI " unsigned int " count );
25 .PP
26 .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
27 .B #include <dirent.h>
28 .PP
29 .BI "ssize_t getdents64(int " fd ", void *" dirp ", size_t " count );
30 .fi
31 .PP
32 .IR Note :
33 glibc provides no wrapper for
34 .BR getdents (),
35 necessitating the use of
36 .BR syscall (2).
37 .PP
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.
61 .PP
62 The
63 .I linux_dirent
64 structure is declared as follows:
65 .PP
66 .in +4n
67 .EX
68 struct linux_dirent {
69 unsigned long d_ino; /* Inode number */
70 unsigned long d_off; /* Offset to next \fIlinux_dirent\fP */
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 */
80 }
81 .EE
82 .in
83 .PP
84 .I d_ino
85 is an inode number.
86 .I d_off
87 is the distance from the start of the directory to the start of the next
88 .IR linux_dirent .
89 .I d_reclen
90 is the size of this entire
91 .IR linux_dirent .
92 .I d_name
93 is a null-terminated filename.
94 .PP
95 .I d_type
96 is a byte at the end of the structure that indicates the file type.
97 It contains one of the following values (defined in
98 .IR <dirent.h> ):
99 .TP 12
100 .B DT_BLK
101 This is a block device.
102 .TP
103 .B DT_CHR
104 This is a character device.
105 .TP
106 .B DT_DIR
107 This is a directory.
108 .TP
109 .B DT_FIFO
110 This is a named pipe (FIFO).
111 .TP
112 .B DT_LNK
113 This is a symbolic link.
114 .TP
115 .B DT_REG
116 This is a regular file.
117 .TP
118 .B DT_SOCK
119 This is a UNIX domain socket.
120 .TP
121 .B DT_UNKNOWN
122 The file type is unknown.
123 .PP
124 The
125 .I d_type
126 field is implemented since Linux 2.6.4.
127 It occupies a space that was previously a zero-filled padding byte in the
128 .I linux_dirent
129 structure.
130 Thus, on kernels up to and including 2.6.3,
131 attempting to access this field always provides the value 0
132 .RB ( DT_UNKNOWN ).
133 .PP
134 Currently,
135 .\" kernel 2.6.27
136 .\" The same sentence is in readdir.2
137 only some filesystems (among them: Btrfs, ext2, ext3, and ext4)
138 have full support for returning the file type in
139 .IR d_type .
140 All applications must properly handle a return of
141 .BR DT_UNKNOWN .
142 .SS getdents64()
143 The original Linux
144 .BR getdents ()
145 system call did not handle large filesystems and large file offsets.
146 Consequently, Linux 2.4 added
147 .BR getdents64 (),
148 with wider types for the
149 .I d_ino
150 and
151 .I d_off
152 fields.
153 In addition,
154 .BR getdents64 ()
155 supports an explicit
156 .I d_type
157 field.
158 .PP
159 The
160 .BR getdents64 ()
161 system call is like
162 .BR getdents (),
163 except that its second argument is a pointer to a buffer containing
164 structures of the following type:
165 .PP
166 .in +4n
167 .EX
168 struct linux_dirent64 {
169 ino64_t d_ino; /* 64\-bit inode number */
170 off64_t d_off; /* 64\-bit offset to next structure */
171 unsigned short d_reclen; /* Size of this dirent */
172 unsigned char d_type; /* File type */
173 char d_name[]; /* Filename (null\-terminated) */
174 };
175 .EE
176 .in
177 .SH RETURN VALUE
178 On success, the number of bytes read is returned.
179 On end of directory, 0 is returned.
180 On error, \-1 is returned, and
181 .I errno
182 is set to indicate the error.
183 .SH ERRORS
184 .TP
185 .B EBADF
186 Invalid file descriptor
187 .IR fd .
188 .TP
189 .B EFAULT
190 Argument points outside the calling process's address space.
191 .TP
192 .B EINVAL
193 Result buffer is too small.
194 .TP
195 .B ENOENT
196 No such directory.
197 .TP
198 .B ENOTDIR
199 File descriptor does not refer to a directory.
200 .SH CONFORMING TO
201 SVr4.
202 .\" SVr4 documents additional ENOLINK, EIO error conditions.
203 .SH NOTES
204 Library support for
205 .BR getdents64 ()
206 was added in glibc 2.30;
207 Glibc does not provide a wrapper for
208 .BR getdents ();
209 call
210 .BR getdents ()
211 (or
212 .BR getdents64 ()
213 on earlier glibc versions) using
214 .BR syscall (2).
215 In that case you will need to define the
216 .I linux_dirent
217 or
218 .I linux_dirent64
219 structure yourself.
220 .PP
221 Probably, you want to use
222 .BR readdir (3)
223 instead of these system calls.
224 .PP
225 These calls supersede
226 .BR readdir (2).
227 .SH EXAMPLES
228 .\" FIXME The example program needs to be revised, since it uses the older
229 .\" getdents() system call and the structure with smaller field widths.
230 The program below demonstrates the use of
231 .BR getdents ().
232 The following output shows an example of what we see when running this
233 program on an ext2 directory:
234 .PP
235 .in +4n
236 .EX
237 .RB "$" " ./a.out /testfs/"
238 -\-\-\-\-\-\-\-\-\-\-\-\-\-\- nread=120 \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
239 inode# file type d_reclen d_off d_name
240 2 directory 16 12 .
241 2 directory 16 24 ..
242 11 directory 24 44 lost+found
243 12 regular 16 56 a
244 228929 directory 16 68 sub
245 16353 directory 16 80 sub2
246 130817 directory 16 4096 sub3
247 .EE
248 .in
249 .SS Program source
250 \&
251 .EX
252 #define _GNU_SOURCE
253 #include <dirent.h> /* Defines DT_* constants */
254 #include <fcntl.h>
255 #include <stdint.h>
256 #include <stdio.h>
257 #include <unistd.h>
258 #include <stdlib.h>
259 #include <sys/stat.h>
260 #include <sys/syscall.h>
261
262 #define handle_error(msg) \e
263 do { perror(msg); exit(EXIT_FAILURE); } while (0)
264
265 struct linux_dirent {
266 unsigned long d_ino;
267 off_t d_off;
268 unsigned short d_reclen;
269 char d_name[];
270 };
271
272 #define BUF_SIZE 1024
273
274 int
275 main(int argc, char *argv[])
276 {
277 int fd;
278 long nread;
279 char buf[BUF_SIZE];
280 struct linux_dirent *d;
281 char d_type;
282
283 fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
284 if (fd == \-1)
285 handle_error("open");
286
287 for (;;) {
288 nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
289 if (nread == \-1)
290 handle_error("getdents");
291
292 if (nread == 0)
293 break;
294
295 printf("\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- nread=%d \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\en", nread);
296 printf("inode# file type d_reclen d_off d_name\en");
297 for (long bpos = 0; bpos < nread;) {
298 d = (struct linux_dirent *) (buf + bpos);
299 printf("%8ld ", d\->d_ino);
300 d_type = *(buf + bpos + d\->d_reclen \- 1);
301 printf("%\-10s ", (d_type == DT_REG) ? "regular" :
302 (d_type == DT_DIR) ? "directory" :
303 (d_type == DT_FIFO) ? "FIFO" :
304 (d_type == DT_SOCK) ? "socket" :
305 (d_type == DT_LNK) ? "symlink" :
306 (d_type == DT_BLK) ? "block dev" :
307 (d_type == DT_CHR) ? "char dev" : "???");
308 printf("%4d %10jd %s\en", d\->d_reclen,
309 (intmax_t) d\->d_off, d\->d_name);
310 bpos += d\->d_reclen;
311 }
312 }
313
314 exit(EXIT_SUCCESS);
315 }
316 .EE
317 .SH SEE ALSO
318 .BR readdir (2),
319 .BR readdir (3),
320 .BR inode (7)