]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man2/ioctl_fat.2
pid_namespaces.7: Minor fixes to Keno Fischer's patch
[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
b8efb414 24.TH IOCTL-FAT 2 2016-10-08 "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>
30.br
31.B #include <sys/ioctl.h>
32.sp
f54da10e
MK
33.BI "int ioctl(int " fd ", FAT_IOCTL_GET_ATTRIBUTES, uint32_t * " attr );
34.BI "int ioctl(int " fd ", FAT_IOCTL_SET_ATTRIBUTES, uint32_t * " attr );
35.BI "int ioctl(int " fd ", FAT_IOCTL_GET_VOLUME_ID, uint32_t * " id );
a1cd6a8f 36.BI "int ioctl(int " fd ", VFAT_IOCTL_READDIR_BOTH,
f54da10e 37.BI " struct __fat_dirent[2] " entry );
a1cd6a8f 38.BI "int ioctl(int " fd ", VFAT_IOCTL_READDIR_SHORT,
f54da10e 39.BI " struct __fat_dirent[2] " entry );
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.
91.SS Reading the volume label
f54da10e 92FAT filesystems are identified by a volume label.
a1cd6a8f
HS
93The volume label 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 label is displayed to the user as a group of two
f54da10e 11016-bit fields:
a1cd6a8f
HS
111.PP
112.in +4n
113.nf
29ff7699 114printf("Volume ID %04x-%04x\\n", id >> 16, id & 0xFFFF);
a1cd6a8f
HS
115.fi
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:
a1cd6a8f
HS
145
146.in +4n
147.nf
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.fi
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.
232
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
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
MK
256.IR /mnt/user/foo :
257
a1cd6a8f
HS
258.in +4n
259.nf
11a86b15 260# ./toggle_fat_archive_flag /mnt/user/foo
a1cd6a8f
HS
261Archive flag is set
262Toggling archive flag
263Archive flag is not set
264.fi
265.in
11a86b15 266.SS Program source (toggle_fat_archive_flag.c)
a1cd6a8f
HS
267.in +4n
268.nf
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\\n");
295 else
296 printf("Archive flag is not set\\n");
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\\n", 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\\n");
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
HS
347}
348.fi
349.in
350.SS Reading the volume label
f54da10e
MK
351The following program demonstrates the use of
352.BR ioctl (2)
353to display the volume label of a FAT filesystem.
a1cd6a8f
HS
354.PP
355The following output was recorded when applying the program for
356directory
f54da10e
MK
357.IR /mnt/user :
358
a1cd6a8f
HS
359.in +4n
360.nf
11a86b15 361$ ./display_fat_volume_id /mnt/user
a1cd6a8f
HS
362Volume ID 6443-6241
363.fi
364.in
11a86b15 365.SS Program source (display_fat_volume_id.c)
a1cd6a8f
HS
366.in +4n
367.nf
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\\n", 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 */
29ff7699 406 printf("Volume ID %04x\-%04x\\n", id >> 16, id & 0xFFFF);
a1cd6a8f
HS
407
408 close(fd);
409
3b4f9570 410 exit(EXIT_SUCCESS);
a1cd6a8f
HS
411}
412.fi
413.in
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 :
421
a1cd6a8f
HS
422.in +4n
423.nf
424$ ./fat_dir /mnt/user
425\[char46] -> ''
426\[char46]. -> ''
427ALONGF~1.TXT -> 'a long filename.txt'
428UPPER.TXT -> ''
429LOWER.TXT -> 'lower.txt'
430.fi
431.in
432.SS Program source
433.in +4n
434.nf
435#include <fcntl.h>
436#include <linux/msdos_fs.h>
437#include <stdio.h>
438#include <stdlib.h>
439#include <sys/ioctl.h>
440#include <unistd.h>
441
442int
443main(int argc, char *argv[])
444{
445 struct __fat_dirent entry[2];
446 int fd;
447 int ret;
448
449 if (argc != 2) {
450 printf("Usage: %s DIRECTORY\\n", argv[0]);
451 exit(EXIT_FAILURE);
452 }
453
454 /*
455 * Open file descriptor for the directory.
456 */
457 fd = open(argv[1], O_RDONLY | O_DIRECTORY);
458 if (fd == \-1) {
459 perror("open");
460 exit(EXIT_FAILURE);
461 }
462
463 for (;;) {
464
465 /*
466 * Read next directory entry.
467 */
468 ret = ioctl( fd, VFAT_IOCTL_READDIR_BOTH, entry);
469
470 /*
471 * If an error occurs, the return value is \-1.
432cdf0d
HS
472 * If the end of the directory list has been reached,
473 * the return value is 0.
474 * For backward compatibility the end of the directory
475 * list is also signaled by d_reclen == 0.
a1cd6a8f 476 */
432cdf0d 477 if (ret < 1)
a1cd6a8f
HS
478 break;
479
480 /*
481 * Write both the short name and the long name.
482 */
483 printf("%s \-> '%s'\\n", entry[0].d_name, entry[1].d_name);
484 }
f54da10e 485
a1cd6a8f
HS
486 if (ret == \-1) {
487 perror("VFAT_IOCTL_READDIR_BOTH");
488 exit(EXIT_FAILURE);
489 }
490
491 /*
492 * Close the file descriptor.
493 */
494 close(fd);
495
3b4f9570 496 exit(EXIT_SUCCESS);
a1cd6a8f
HS
497}
498.fi
499.in
500.SH SEE ALSO
501.BR ioctl (2)