]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man2/ioctl_fat.2
prctl.2: ffix
[thirdparty/man-pages.git] / man2 / ioctl_fat.2
CommitLineData
a1cd6a8f
HS
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
3a6b9445
MK
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
a1cd6a8f
HS
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
9ba01802 24.TH IOCTL-FAT 2 2019-03-06 "Linux" "Linux Programmer's Manual"
d282bb24 25.SH NAME
f54da10e 26ioctl_fat \- manipulating the FAT filesystem
a1cd6a8f
HS
27.SH SYNOPSIS
28.nf
29.B #include <linux/msdos_fs.h>
a1cd6a8f 30.B #include <sys/ioctl.h>
68e4db0a 31.PP
70bdb9b5
MK
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 );
a1cd6a8f 35.BI "int ioctl(int " fd ", VFAT_IOCTL_READDIR_BOTH,
f54da10e 36.BI " struct __fat_dirent[2] " entry );
a1cd6a8f 37.BI "int ioctl(int " fd ", VFAT_IOCTL_READDIR_SHORT,
f54da10e 38.BI " struct __fat_dirent[2] " entry );
3b3b8d5d 39.fi
a1cd6a8f
HS
40.SH DESCRIPTION
41The
42.BR ioctl (2)
f54da10e 43system call can be used to read and write metadata of FAT filesystems that
a1cd6a8f
HS
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
f54da10e 54argument contains a file descriptor for a file or directory.
a1cd6a8f
HS
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
f54da10e
MK
63argument contains a pointer to a bit mask.
64The bits of the bit mask are:
a1cd6a8f
HS
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.
9aa10c77
BM
91.SS Reading the volume ID
92FAT filesystems are identified by a volume ID.
93The volume ID can be read with
a1cd6a8f
HS
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.
9aa10c77 109Typically the volume ID is displayed to the user as a group of two
f54da10e 11016-bit fields:
a1cd6a8f
HS
111.PP
112.in +4n
18ef2552 113.EX
d1a71985 114printf("Volume ID %04x-%04x\en", id >> 16, id & 0xFFFF);
18ef2552 115.EE
a1cd6a8f
HS
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.
f54da10e 137The file descriptor can be used only once to iterate over the directory
a1cd6a8f
HS
138entries by calling
139.BR ioctl (2)
140repeatedly.
141.PP
142The
143.I entry
f54da10e 144argument is a two-element array of the following structures:
efeece04 145.PP
a1cd6a8f 146.in +4n
18ef2552 147.EX
a1cd6a8f
HS
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};
18ef2552 154.EE
a1cd6a8f
HS
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
d4e32096 160The
432cdf0d
HS
161.I d_ino
162and
163.I d_off
d4e32096
MK
164fields are filled only for long filenames.
165The
432cdf0d 166.I d_ino
d4e32096
MK
167field holds the inode number of the directory.
168The
432cdf0d 169.I d_off
d4e32096 170field holds the offset of the file entry in the directory.
432cdf0d
HS
171As these values are not available for short filenames, the user code should
172simply ignore them.
173.PP
f54da10e 174The field
a1cd6a8f 175.I d_reclen
f54da10e 176contains the length of the filename in the field
a1cd6a8f 177.IR d_name .
d4e32096 178To keep backward compatibility, a length of 0 for the short filename signals
432cdf0d 179that the end of the directory has been reached.
d4e32096
MK
180However, the preferred method for detecting the end of the directory
181is to test the
ab57579b 182.BR ioctl (2)
d4e32096 183return value.
432cdf0d
HS
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.
a1cd6a8f 189.SH RETURN VALUE
f54da10e
MK
190On error, \-1 is returned, and
191.I errno
192is set to indicate the error.
432cdf0d
HS
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.
a1cd6a8f
HS
200.SH ERRORS
201.TP
432cdf0d 202.B ENOENT
a1cd6a8f 203This error is returned by
432cdf0d
HS
204.B VFAT_IOCTL_READDIR_BOTH
205and
a1cd6a8f 206.B VFAT_IOCTL_READDIR_SHORT
432cdf0d
HS
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
a1cd6a8f
HS
214and
215.B VFAT_IOCTL_READDIR_SHORT
432cdf0d 216if the file descriptor
f54da10e
MK
217.I fd
218does not refer to a directory.
a1cd6a8f
HS
219.TP
220.B ENOTTY
f54da10e
MK
221The file descriptor
222.I fd
223does not refer to an object in a FAT filesystem.
a1cd6a8f 224.PP
f54da10e 225For further error values, see
a1cd6a8f
HS
226.BR ioctl (2).
227.SH VERSIONS
3289445e
MK
228.BR VFAT_IOCTL_READDIR_BOTH
229and
230.B VFAT_IOCTL_READDIR_SHORT
231first appeared in Linux 2.0.
efeece04 232.PP
3289445e
MK
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.
efeece04 239.PP
a1cd6a8f 240.B FAT_IOCTL_GET_VOLUME_ID
f54da10e
MK
241was introduced in version 3.11
242.\" commit 6e5b93ee55d401f1619092fb675b57c28c9ed7ec
243of the Linux kernel.
d282bb24 244.SH CONFORMING TO
a1cd6a8f
HS
245This API is Linux-specific.
246.SH EXAMPLE
247.SS Toggling the archive flag
f54da10e 248The following program demonstrates the usage of
ab57579b 249.BR ioctl (2)
f54da10e
MK
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.
a1cd6a8f
HS
254.PP
255The following was recorded when applying the program for the file
f54da10e 256.IR /mnt/user/foo :
efeece04 257.PP
a1cd6a8f 258.in +4n
18ef2552 259.EX
11a86b15 260# ./toggle_fat_archive_flag /mnt/user/foo
a1cd6a8f
HS
261Archive flag is set
262Toggling archive flag
263Archive flag is not set
18ef2552 264.EE
a1cd6a8f 265.in
11a86b15 266.SS Program source (toggle_fat_archive_flag.c)
18ef2552
MK
267\&
268.EX
a1cd6a8f
HS
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)
d1a71985 294 printf("Archive flag is set\en");
a1cd6a8f 295 else
d1a71985 296 printf("Archive flag is not set\en");
a1cd6a8f
HS
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) {
d1a71985 309 printf("Usage: %s FILENAME\en", argv[0]);
a1cd6a8f
HS
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 */
d1a71985 327 printf("Toggling archive flag\en");
a1cd6a8f
HS
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
3b4f9570 346 exit(EXIT_SUCCESS);
a1cd6a8f 347}
18ef2552
MK
348.EE
349.\"
9aa10c77 350.SS Reading the volume ID
f54da10e
MK
351The following program demonstrates the use of
352.BR ioctl (2)
9aa10c77 353to display the volume ID of a FAT filesystem.
a1cd6a8f
HS
354.PP
355The following output was recorded when applying the program for
356directory
f54da10e 357.IR /mnt/user :
efeece04 358.PP
a1cd6a8f 359.in +4n
18ef2552 360.EX
11a86b15 361$ ./display_fat_volume_id /mnt/user
a1cd6a8f 362Volume ID 6443-6241
18ef2552 363.EE
a1cd6a8f 364.in
11a86b15 365.SS Program source (display_fat_volume_id.c)
18ef2552
MK
366\&
367.EX
a1cd6a8f
HS
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) {
d1a71985 384 printf("Usage: %s FILENAME\en", argv[0]);
a1cd6a8f
HS
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 */
d1a71985 406 printf("Volume ID %04x\-%04x\en", id >> 16, id & 0xFFFF);
a1cd6a8f
HS
407
408 close(fd);
409
3b4f9570 410 exit(EXIT_SUCCESS);
a1cd6a8f 411}
18ef2552
MK
412.EE
413.\"
a1cd6a8f 414.SS Listing a directory
f54da10e
MK
415The following program demonstrates the use of
416.BR ioctl (2)
417to list a directory.
a1cd6a8f 418.PP
f54da10e
MK
419The following was recorded when applying the program to the directory
420.IR /mnt/user :
efeece04 421.PP
a1cd6a8f 422.in +4n
18ef2552
MK
423.EX
424$ \fB./fat_dir /mnt/user\fP
a1cd6a8f
HS
425\[char46] -> ''
426\[char46]. -> ''
427ALONGF~1.TXT -> 'a long filename.txt'
428UPPER.TXT -> ''
429LOWER.TXT -> 'lower.txt'
18ef2552 430.EE
a1cd6a8f 431.in
18ef2552 432.\"
a1cd6a8f
HS
433.SS Program source
434.in +4n
e7d0bb47 435.EX
a1cd6a8f
HS
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) {
d1a71985 451 printf("Usage: %s DIRECTORY\en", argv[0]);
a1cd6a8f
HS
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.
432cdf0d
HS
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.
a1cd6a8f 477 */
432cdf0d 478 if (ret < 1)
a1cd6a8f
HS
479 break;
480
481 /*
482 * Write both the short name and the long name.
483 */
d1a71985 484 printf("%s \-> '%s'\en", entry[0].d_name, entry[1].d_name);
a1cd6a8f 485 }
f54da10e 486
a1cd6a8f
HS
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
3b4f9570 497 exit(EXIT_SUCCESS);
a1cd6a8f 498}
e7d0bb47 499.EE
a1cd6a8f
HS
500.in
501.SH SEE ALSO
502.BR ioctl (2)