]> git.ipfire.org Git - thirdparty/man-pages.git/blame_incremental - man2/ioctl_fat.2
prctl.2: ffix
[thirdparty/man-pages.git] / man2 / ioctl_fat.2
... / ...
CommitLineData
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
26ioctl_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
41The
42.BR ioctl (2)
43system call can be used to read and write metadata of FAT filesystems that
44are not accessible using other system calls.
45.SS Reading and setting file attributes
46Files and directories in the FAT filesystem possess an attribute bit mask that
47can be read with
48.B FAT_IOCTL_GET_ATTRIBUTES
49and written with
50.BR FAT_IOCTL_SET_ATTRIBUTES .
51.PP
52The
53.I fd
54argument contains a file descriptor for a file or directory.
55It is sufficient to create the file descriptor by calling
56.BR open (2)
57with the
58.B O_RDONLY
59flag.
60.PP
61The
62.I attr
63argument contains a pointer to a bit mask.
64The bits of the bit mask are:
65.TP
66.B ATTR_RO
67This bit specifies that the file or directory is read-only.
68.TP
69.B ATTR_HIDDEN
70This bit specifies that the file or directory is hidden.
71.TP
72.B ATTR_SYS
73This bit specifies that the file is a system file.
74.TP
75.B ATTR_VOLUME
76This bit specifies that the file is a volume label.
77This attribute is read-only.
78.TP
79.B ATTR_DIR
80This bit specifies that this is a directory.
81This attribute is read-only.
82.TP
83.B ATTR_ARCH
84This bit indicates that this file or directory should be archived.
85It is set when a file is created or modified.
86It is reset by an archiving system.
87.PP
88The zero value
89.B ATTR_NONE
90can be used to indicate that no attribute bit is set.
91.SS Reading the volume ID
92FAT filesystems are identified by a volume ID.
93The volume ID can be read with
94.BR FAT_IOCTL_GET_VOLUME_ID .
95.PP
96The
97.I fd
98argument can be a file descriptor for any file or directory of the
99filesystem.
100It is sufficient to create the file descriptor by calling
101.BR open (2)
102with the
103.B O_RDONLY
104flag.
105.PP
106The
107.I id
108argument is a pointer to the field that will be filled with the volume ID.
109Typically the volume ID is displayed to the user as a group of two
11016-bit fields:
111.PP
112.in +4n
113.EX
114printf("Volume ID %04x-%04x\en", id >> 16, id & 0xFFFF);
115.EE
116.in
117.SS Reading short file names of a directory
118A file or directory on a FAT filesystem always has a short filename
119consisting of up to 8 capital letters, optionally followed by a period
120and up to 3 capital letters for the file extension.
121If the actual filename does not fit into this scheme, it is stored
122as a long filename of up to 255 UTF-16 characters.
123.PP
124The short filenames in a directory can be read with
125.BR VFAT_IOCTL_READDIR_SHORT .
126.B VFAT_IOCTL_READDIR_BOTH
127reads both the short and the long filenames.
128.PP
129The
130.I fd
131argument must be a file descriptor for a directory.
132It is sufficient to create the file descriptor by calling
133.BR open (2)
134with the
135.B O_RDONLY
136flag.
137The file descriptor can be used only once to iterate over the directory
138entries by calling
139.BR ioctl (2)
140repeatedly.
141.PP
142The
143.I entry
144argument is a two-element array of the following structures:
145.PP
146.in +4n
147.EX
148struct __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
157The first entry in the array is for the short filename.
158The second entry is for the long filename.
159.PP
160The
161.I d_ino
162and
163.I d_off
164fields are filled only for long filenames.
165The
166.I d_ino
167field holds the inode number of the directory.
168The
169.I d_off
170field holds the offset of the file entry in the directory.
171As these values are not available for short filenames, the user code should
172simply ignore them.
173.PP
174The field
175.I d_reclen
176contains the length of the filename in the field
177.IR d_name .
178To keep backward compatibility, a length of 0 for the short filename signals
179that the end of the directory has been reached.
180However, the preferred method for detecting the end of the directory
181is to test the
182.BR ioctl (2)
183return value.
184If no long filename exists, field
185.I d_reclen
186is set to 0 and
187.I d_name
188is a character string of length 0 for the long filename.
189.SH RETURN VALUE
190On error, \-1 is returned, and
191.I errno
192is set to indicate the error.
193.PP
194For
195.B VFAT_IOCTL_READDIR_BOTH
196and
197.B VFAT_IOCTL_READDIR_SHORT
198a return value of 1 signals that a new directory entry has been read and
199a return value of 0 signals that the end of the directory has been reached.
200.SH ERRORS
201.TP
202.B ENOENT
203This error is returned by
204.B VFAT_IOCTL_READDIR_BOTH
205and
206.B VFAT_IOCTL_READDIR_SHORT
207if the file descriptor
208.I fd
209refers to a removed, but still open directory.
210.TP
211.B ENOTDIR
212This error is returned by
213.B VFAT_IOCTL_READDIR_BOTH
214and
215.B VFAT_IOCTL_READDIR_SHORT
216if the file descriptor
217.I fd
218does not refer to a directory.
219.TP
220.B ENOTTY
221The file descriptor
222.I fd
223does not refer to an object in a FAT filesystem.
224.PP
225For further error values, see
226.BR ioctl (2).
227.SH VERSIONS
228.BR VFAT_IOCTL_READDIR_BOTH
229and
230.B VFAT_IOCTL_READDIR_SHORT
231first appeared in Linux 2.0.
232.PP
233.BR FAT_IOCTL_GET_ATTRIBUTES
234and
235.BR FAT_IOCTL_SET_ATTRIBUTES
236first appeared
237.\" just before we got Git history
238in Linux 2.6.12.
239.PP
240.B FAT_IOCTL_GET_VOLUME_ID
241was introduced in version 3.11
242.\" commit 6e5b93ee55d401f1619092fb675b57c28c9ed7ec
243of the Linux kernel.
244.SH CONFORMING TO
245This API is Linux-specific.
246.SH EXAMPLE
247.SS Toggling the archive flag
248The following program demonstrates the usage of
249.BR ioctl (2)
250to manipulate file attributes.
251The program reads and displays the archive attribute of a file.
252After inverting the value of the attribute,
253the program reads and displays the attribute again.
254.PP
255The 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
261Archive flag is set
262Toggling archive flag
263Archive 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 */
281static uint32_t
282readattr(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
301int
302main(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
351The following program demonstrates the use of
352.BR ioctl (2)
353to display the volume ID of a FAT filesystem.
354.PP
355The following output was recorded when applying the program for
356directory
357.IR /mnt/user :
358.PP
359.in +4n
360.EX
361$ ./display_fat_volume_id /mnt/user
362Volume 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
376int
377main(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
415The following program demonstrates the use of
416.BR ioctl (2)
417to list a directory.
418.PP
419The 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]. -> ''
427ALONGF~1.TXT -> 'a long filename.txt'
428UPPER.TXT -> ''
429LOWER.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
443int
444main(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)