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