]> git.ipfire.org Git - thirdparty/man-pages.git/blob - man2/ioctl_fat.2
d498a2823e08331c96df4350e3c99662a014e5ce
[thirdparty/man-pages.git] / man2 / ioctl_fat.2
1 .\" Copyright (C) 2014, Heinrich Schuchardt <xypron.glpk@gmx.de>
2 .\"
3 .\" SPDX-License-Identifier: Linux-man-pages-copyleft
4 .TH IOCTL_FAT 2 2021-03-22 "Linux" "Linux Programmer's Manual"
5 .SH NAME
6 ioctl_fat \- manipulating the FAT filesystem
7 .SH LIBRARY
8 Standard C library
9 .RI ( libc ", " \-lc )
10 .SH SYNOPSIS
11 .nf
12 .BR "#include <linux/msdos_fs.h>" " /* Definition of [" V ] FAT_* " and"
13 .BR " ATTR_* " constants */"
14 .B #include <sys/ioctl.h>
15 .PP
16 .BI "int ioctl(int " fd ", FAT_IOCTL_GET_ATTRIBUTES, uint32_t *" attr );
17 .BI "int ioctl(int " fd ", FAT_IOCTL_SET_ATTRIBUTES, uint32_t *" attr );
18 .BI "int ioctl(int " fd ", FAT_IOCTL_GET_VOLUME_ID, uint32_t *" id );
19 .BI "int ioctl(int " fd ", VFAT_IOCTL_READDIR_BOTH,"
20 .BI " struct __fat_dirent " entry [2]);
21 .BI "int ioctl(int " fd ", VFAT_IOCTL_READDIR_SHORT,"
22 .BI " struct __fat_dirent " entry [2]);
23 .fi
24 .SH DESCRIPTION
25 The
26 .BR ioctl (2)
27 system call can be used to read and write metadata of FAT filesystems that
28 are not accessible using other system calls.
29 .SS Reading and setting file attributes
30 Files and directories in the FAT filesystem possess an attribute bit mask that
31 can be read with
32 .B FAT_IOCTL_GET_ATTRIBUTES
33 and written with
34 .BR FAT_IOCTL_SET_ATTRIBUTES .
35 .PP
36 The
37 .I fd
38 argument contains a file descriptor for a file or directory.
39 It is sufficient to create the file descriptor by calling
40 .BR open (2)
41 with the
42 .B O_RDONLY
43 flag.
44 .PP
45 The
46 .I attr
47 argument contains a pointer to a bit mask.
48 The bits of the bit mask are:
49 .TP
50 .B ATTR_RO
51 This bit specifies that the file or directory is read-only.
52 .TP
53 .B ATTR_HIDDEN
54 This bit specifies that the file or directory is hidden.
55 .TP
56 .B ATTR_SYS
57 This bit specifies that the file is a system file.
58 .TP
59 .B ATTR_VOLUME
60 This bit specifies that the file is a volume label.
61 This attribute is read-only.
62 .TP
63 .B ATTR_DIR
64 This bit specifies that this is a directory.
65 This attribute is read-only.
66 .TP
67 .B ATTR_ARCH
68 This bit indicates that this file or directory should be archived.
69 It is set when a file is created or modified.
70 It is reset by an archiving system.
71 .PP
72 The zero value
73 .B ATTR_NONE
74 can be used to indicate that no attribute bit is set.
75 .SS Reading the volume ID
76 FAT filesystems are identified by a volume ID.
77 The volume ID can be read with
78 .BR FAT_IOCTL_GET_VOLUME_ID .
79 .PP
80 The
81 .I fd
82 argument can be a file descriptor for any file or directory of the
83 filesystem.
84 It is sufficient to create the file descriptor by calling
85 .BR open (2)
86 with the
87 .B O_RDONLY
88 flag.
89 .PP
90 The
91 .I id
92 argument is a pointer to the field that will be filled with the volume ID.
93 Typically the volume ID is displayed to the user as a group of two
94 16-bit fields:
95 .PP
96 .in +4n
97 .EX
98 printf("Volume ID %04x\-%04x\en", id >> 16, id & 0xFFFF);
99 .EE
100 .in
101 .SS Reading short filenames of a directory
102 A file or directory on a FAT filesystem always has a short filename
103 consisting of up to 8 capital letters, optionally followed by a period
104 and up to 3 capital letters for the file extension.
105 If the actual filename does not fit into this scheme, it is stored
106 as a long filename of up to 255 UTF-16 characters.
107 .PP
108 The short filenames in a directory can be read with
109 .BR VFAT_IOCTL_READDIR_SHORT .
110 .B VFAT_IOCTL_READDIR_BOTH
111 reads both the short and the long filenames.
112 .PP
113 The
114 .I fd
115 argument must be a file descriptor for a directory.
116 It is sufficient to create the file descriptor by calling
117 .BR open (2)
118 with the
119 .B O_RDONLY
120 flag.
121 The file descriptor can be used only once to iterate over the directory
122 entries by calling
123 .BR ioctl (2)
124 repeatedly.
125 .PP
126 The
127 .I entry
128 argument is a two-element array of the following structures:
129 .PP
130 .in +4n
131 .EX
132 struct __fat_dirent {
133 long d_ino;
134 __kernel_off_t d_off;
135 uint32_t short d_reclen;
136 char d_name[256];
137 };
138 .EE
139 .in
140 .PP
141 The first entry in the array is for the short filename.
142 The second entry is for the long filename.
143 .PP
144 The
145 .I d_ino
146 and
147 .I d_off
148 fields are filled only for long filenames.
149 The
150 .I d_ino
151 field holds the inode number of the directory.
152 The
153 .I d_off
154 field holds the offset of the file entry in the directory.
155 As these values are not available for short filenames, the user code should
156 simply ignore them.
157 .PP
158 The field
159 .I d_reclen
160 contains the length of the filename in the field
161 .IR d_name .
162 To keep backward compatibility, a length of 0 for the short filename signals
163 that the end of the directory has been reached.
164 However, the preferred method for detecting the end of the directory
165 is to test the
166 .BR ioctl (2)
167 return value.
168 If no long filename exists, field
169 .I d_reclen
170 is set to 0 and
171 .I d_name
172 is a character string of length 0 for the long filename.
173 .SH RETURN VALUE
174 On error, \-1 is returned, and
175 .I errno
176 is set to indicate the error.
177 .PP
178 For
179 .B VFAT_IOCTL_READDIR_BOTH
180 and
181 .B VFAT_IOCTL_READDIR_SHORT
182 a return value of 1 signals that a new directory entry has been read and
183 a return value of 0 signals that the end of the directory has been reached.
184 .SH ERRORS
185 .TP
186 .B ENOENT
187 This error is returned by
188 .B VFAT_IOCTL_READDIR_BOTH
189 and
190 .B VFAT_IOCTL_READDIR_SHORT
191 if the file descriptor
192 .I fd
193 refers to a removed, but still open directory.
194 .TP
195 .B ENOTDIR
196 This error is returned by
197 .B VFAT_IOCTL_READDIR_BOTH
198 and
199 .B VFAT_IOCTL_READDIR_SHORT
200 if the file descriptor
201 .I fd
202 does not refer to a directory.
203 .TP
204 .B ENOTTY
205 The file descriptor
206 .I fd
207 does not refer to an object in a FAT filesystem.
208 .PP
209 For further error values, see
210 .BR ioctl (2).
211 .SH VERSIONS
212 .BR VFAT_IOCTL_READDIR_BOTH
213 and
214 .B VFAT_IOCTL_READDIR_SHORT
215 first appeared in Linux 2.0.
216 .PP
217 .BR FAT_IOCTL_GET_ATTRIBUTES
218 and
219 .BR FAT_IOCTL_SET_ATTRIBUTES
220 first appeared
221 .\" just before we got Git history
222 in Linux 2.6.12.
223 .PP
224 .B FAT_IOCTL_GET_VOLUME_ID
225 was introduced in version 3.11
226 .\" commit 6e5b93ee55d401f1619092fb675b57c28c9ed7ec
227 of the Linux kernel.
228 .SH CONFORMING TO
229 This API is Linux-specific.
230 .SH EXAMPLES
231 .SS Toggling the archive flag
232 The following program demonstrates the usage of
233 .BR ioctl (2)
234 to manipulate file attributes.
235 The program reads and displays the archive attribute of a file.
236 After inverting the value of the attribute,
237 the program reads and displays the attribute again.
238 .PP
239 The following was recorded when applying the program for the file
240 .IR /mnt/user/foo :
241 .PP
242 .in +4n
243 .EX
244 # ./toggle_fat_archive_flag /mnt/user/foo
245 Archive flag is set
246 Toggling archive flag
247 Archive flag is not set
248 .EE
249 .in
250 .SS Program source (toggle_fat_archive_flag.c)
251 \&
252 .EX
253 #include <fcntl.h>
254 #include <linux/msdos_fs.h>
255 #include <stdint.h>
256 #include <stdio.h>
257 #include <stdlib.h>
258 #include <sys/ioctl.h>
259 #include <unistd.h>
260
261 /*
262 * Read file attributes of a file on a FAT filesystem.
263 * Output the state of the archive flag.
264 */
265 static uint32_t
266 readattr(int fd)
267 {
268 uint32_t attr;
269 int ret;
270
271 ret = ioctl(fd, FAT_IOCTL_GET_ATTRIBUTES, &attr);
272 if (ret == \-1) {
273 perror("ioctl");
274 exit(EXIT_FAILURE);
275 }
276
277 if (attr & ATTR_ARCH)
278 printf("Archive flag is set\en");
279 else
280 printf("Archive flag is not set\en");
281
282 return attr;
283 }
284
285 int
286 main(int argc, char *argv[])
287 {
288 uint32_t attr;
289 int fd;
290 int ret;
291
292 if (argc != 2) {
293 printf("Usage: %s FILENAME\en", argv[0]);
294 exit(EXIT_FAILURE);
295 }
296
297 fd = open(argv[1], O_RDONLY);
298 if (fd == \-1) {
299 perror("open");
300 exit(EXIT_FAILURE);
301 }
302
303 /*
304 * Read and display the FAT file attributes.
305 */
306 attr = readattr(fd);
307
308 /*
309 * Invert archive attribute.
310 */
311 printf("Toggling archive flag\en");
312 attr \(ha= ATTR_ARCH;
313
314 /*
315 * Write the changed FAT file attributes.
316 */
317 ret = ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr);
318 if (ret == \-1) {
319 perror("ioctl");
320 exit(EXIT_FAILURE);
321 }
322
323 /*
324 * Read and display the FAT file attributes.
325 */
326 readattr(fd);
327
328 close(fd);
329
330 exit(EXIT_SUCCESS);
331 }
332 .EE
333 .\"
334 .SS Reading the volume ID
335 The following program demonstrates the use of
336 .BR ioctl (2)
337 to display the volume ID of a FAT filesystem.
338 .PP
339 The following output was recorded when applying the program for
340 directory
341 .IR /mnt/user :
342 .PP
343 .in +4n
344 .EX
345 $ ./display_fat_volume_id /mnt/user
346 Volume ID 6443\-6241
347 .EE
348 .in
349 .SS Program source (display_fat_volume_id.c)
350 \&
351 .EX
352 #include <fcntl.h>
353 #include <linux/msdos_fs.h>
354 #include <stdint.h>
355 #include <stdio.h>
356 #include <stdlib.h>
357 #include <sys/ioctl.h>
358 #include <unistd.h>
359
360 int
361 main(int argc, char *argv[])
362 {
363 uint32_t id;
364 int fd;
365 int ret;
366
367 if (argc != 2) {
368 printf("Usage: %s FILENAME\en", argv[0]);
369 exit(EXIT_FAILURE);
370 }
371
372 fd = open(argv[1], O_RDONLY);
373 if (fd == \-1) {
374 perror("open");
375 exit(EXIT_FAILURE);
376 }
377
378 /*
379 * Read volume ID.
380 */
381 ret = ioctl(fd, FAT_IOCTL_GET_VOLUME_ID, &id);
382 if (ret == \-1) {
383 perror("ioctl");
384 exit(EXIT_FAILURE);
385 }
386
387 /*
388 * Format the output as two groups of 16 bits each.
389 */
390 printf("Volume ID %04x\-%04x\en", id >> 16, id & 0xFFFF);
391
392 close(fd);
393
394 exit(EXIT_SUCCESS);
395 }
396 .EE
397 .\"
398 .SS Listing a directory
399 The following program demonstrates the use of
400 .BR ioctl (2)
401 to list a directory.
402 .PP
403 The following was recorded when applying the program to the directory
404 .IR /mnt/user :
405 .PP
406 .in +4n
407 .EX
408 $ \fB./fat_dir /mnt/user\fP
409 \[char46] \-> \(aq\(aq
410 \[char46]. \-> \(aq\(aq
411 ALONGF\(ti1.TXT \-> \(aqa long filename.txt\(aq
412 UPPER.TXT \-> \(aq\(aq
413 LOWER.TXT \-> \(aqlower.txt\(aq
414 .EE
415 .in
416 .\"
417 .SS Program source
418 .in +4n
419 .EX
420 #include <fcntl.h>
421 #include <linux/msdos_fs.h>
422 #include <stdio.h>
423 #include <stdlib.h>
424 #include <sys/ioctl.h>
425 #include <unistd.h>
426
427 int
428 main(int argc, char *argv[])
429 {
430 struct __fat_dirent entry[2];
431 int fd;
432 int ret;
433
434 if (argc != 2) {
435 printf("Usage: %s DIRECTORY\en", argv[0]);
436 exit(EXIT_FAILURE);
437 }
438
439 /*
440 * Open file descriptor for the directory.
441 */
442 fd = open(argv[1], O_RDONLY | O_DIRECTORY);
443 if (fd == \-1) {
444 perror("open");
445 exit(EXIT_FAILURE);
446 }
447
448 for (;;) {
449
450 /*
451 * Read next directory entry.
452 */
453 ret = ioctl( fd, VFAT_IOCTL_READDIR_BOTH, entry);
454
455 /*
456 * If an error occurs, the return value is \-1.
457 * If the end of the directory list has been reached,
458 * the return value is 0.
459 * For backward compatibility the end of the directory
460 * list is also signaled by d_reclen == 0.
461 */
462 if (ret < 1)
463 break;
464
465 /*
466 * Write both the short name and the long name.
467 */
468 printf("%s \-> \(aq%s\(aq\en", entry[0].d_name, entry[1].d_name);
469 }
470
471 if (ret == \-1) {
472 perror("VFAT_IOCTL_READDIR_BOTH");
473 exit(EXIT_FAILURE);
474 }
475
476 /*
477 * Close the file descriptor.
478 */
479 close(fd);
480
481 exit(EXIT_SUCCESS);
482 }
483 .EE
484 .in
485 .SH SEE ALSO
486 .BR ioctl (2)