]> git.ipfire.org Git - thirdparty/man-pages.git/blame - man2/ioctl_fat.2
ioctl_fat.2: d_ino, d_off, return value explained
[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
24.TH IOCTl-FAT 2 2015-01-23 "Linux" "Linux Programmer's Manual"
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
114printf("Volume ID %4x-%4x\\n", id >> 16, id & 0xFFFF);
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
432cdf0d
HS
160Fields
161.I d_ino
162and
163.I d_off
164are only filled for long filenames.
165Field
166.I d_ino
167holds the inode number of the directory.
168Field
169.I d_off
170holds 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
f54da10e 174The field
a1cd6a8f 175.I d_reclen
f54da10e 176contains the length of the filename in the field
a1cd6a8f 177.IR d_name .
432cdf0d
HS
178To keep backwards compatibility a length of 0 for the short filename signals
179that the end of the directory has been reached.
180The user code should rely on the return value to identify the end of the
181directory.
182If no long filename exists, field
183.I d_reclen
184is set to 0 and
185.I d_name
186is a character string of length 0 for the long filename.
a1cd6a8f 187.SH RETURN VALUE
f54da10e
MK
188On error, \-1 is returned, and
189.I errno
190is set to indicate the error.
432cdf0d
HS
191.PP
192For
193.B VFAT_IOCTL_READDIR_BOTH
194and
195.B VFAT_IOCTL_READDIR_SHORT
196a return value of 1 signals that a new directory entry has been read and
197a return value of 0 signals that the end of the directory has been reached.
a1cd6a8f
HS
198.SH ERRORS
199.TP
432cdf0d 200.B ENOENT
a1cd6a8f 201This error is returned by
432cdf0d
HS
202.B VFAT_IOCTL_READDIR_BOTH
203and
a1cd6a8f 204.B VFAT_IOCTL_READDIR_SHORT
432cdf0d
HS
205if the file descriptor
206.I fd
207refers to a removed, but still open directory.
208.TP
209.B ENOTDIR
210This error is returned by
211.B VFAT_IOCTL_READDIR_BOTH
a1cd6a8f
HS
212and
213.B VFAT_IOCTL_READDIR_SHORT
432cdf0d 214if the file descriptor
f54da10e
MK
215.I fd
216does not refer to a directory.
a1cd6a8f
HS
217.TP
218.B ENOTTY
f54da10e
MK
219The file descriptor
220.I fd
221does not refer to an object in a FAT filesystem.
a1cd6a8f 222.PP
f54da10e 223For further error values, see
a1cd6a8f
HS
224.BR ioctl (2).
225.SH VERSIONS
3289445e
MK
226.BR VFAT_IOCTL_READDIR_BOTH
227and
228.B VFAT_IOCTL_READDIR_SHORT
229first appeared in Linux 2.0.
230
231.BR FAT_IOCTL_GET_ATTRIBUTES
232and
233.BR FAT_IOCTL_SET_ATTRIBUTES
234first appeared
235.\" just before we got Git history
236in Linux 2.6.12.
237
a1cd6a8f 238.B FAT_IOCTL_GET_VOLUME_ID
f54da10e
MK
239was introduced in version 3.11
240.\" commit 6e5b93ee55d401f1619092fb675b57c28c9ed7ec
241of the Linux kernel.
a1cd6a8f
HS
242.SH "CONFORMING TO"
243This API is Linux-specific.
244.SH EXAMPLE
245.SS Toggling the archive flag
f54da10e
MK
246The following program demonstrates the usage of
247.BR ioctl ()
248to manipulate file attributes.
249The program reads and displays the archive attribute of a file.
250After inverting the value of the attribute,
251the program reads and displays the attribute again.
a1cd6a8f
HS
252.PP
253The following was recorded when applying the program for the file
f54da10e
MK
254.IR /mnt/user/foo :
255
a1cd6a8f
HS
256.in +4n
257.nf
11a86b15 258# ./toggle_fat_archive_flag /mnt/user/foo
a1cd6a8f
HS
259Archive flag is set
260Toggling archive flag
261Archive flag is not set
262.fi
263.in
11a86b15 264.SS Program source (toggle_fat_archive_flag.c)
a1cd6a8f
HS
265.in +4n
266.nf
267#include <fcntl.h>
268#include <linux/msdos_fs.h>
269#include <stdint.h>
270#include <stdio.h>
271#include <stdlib.h>
272#include <sys/ioctl.h>
273#include <unistd.h>
274
275/*
276 * Read file attributes of a file on a FAT filesystem.
277 * Output the state of the archive flag.
278 */
279static uint32_t
280readattr(int fd)
281{
282 uint32_t attr;
283 int ret;
284
285 ret = ioctl(fd, FAT_IOCTL_GET_ATTRIBUTES, &attr);
286 if (ret == \-1) {
287 perror("ioctl");
288 exit(EXIT_FAILURE);
289 }
290
291 if (attr & ATTR_ARCH)
292 printf("Archive flag is set\\n");
293 else
294 printf("Archive flag is not set\\n");
295
296 return attr;
297}
298
299int
300main(int argc, char *argv[])
301{
302 uint32_t attr;
303 int fd;
304 int ret;
305
306 if (argc != 2) {
307 printf("Usage: %s FILENAME\\n", argv[0]);
308 exit(EXIT_FAILURE);
309 }
310
311 fd = open(argv[1], O_RDONLY);
312 if (fd == \-1) {
313 perror("open");
314 exit(EXIT_FAILURE);
315 }
316
317 /*
318 * Read and display the FAT file attributes.
319 */
320 attr = readattr(fd);
321
322 /*
323 * Invert archive attribute.
324 */
325 printf("Toggling archive flag\\n");
326 attr ^= ATTR_ARCH;
327
328 /*
329 * Write the changed FAT file attributes.
330 */
331 ret = ioctl(fd, FAT_IOCTL_SET_ATTRIBUTES, &attr);
332 if (ret == \-1) {
333 perror("ioctl");
334 exit(EXIT_FAILURE);
335 }
336
337 /*
338 * Read and display the FAT file attributes.
339 */
340 readattr(fd);
341
342 close(fd);
343
3b4f9570 344 exit(EXIT_SUCCESS);
a1cd6a8f
HS
345}
346.fi
347.in
348.SS Reading the volume label
f54da10e
MK
349The following program demonstrates the use of
350.BR ioctl (2)
351to display the volume label of a FAT filesystem.
a1cd6a8f
HS
352.PP
353The following output was recorded when applying the program for
354directory
f54da10e
MK
355.IR /mnt/user :
356
a1cd6a8f
HS
357.in +4n
358.nf
11a86b15 359$ ./display_fat_volume_id /mnt/user
a1cd6a8f
HS
360Volume ID 6443-6241
361.fi
362.in
11a86b15 363.SS Program source (display_fat_volume_id.c)
a1cd6a8f
HS
364.in +4n
365.nf
366#include <fcntl.h>
367#include <linux/msdos_fs.h>
368#include <stdint.h>
369#include <stdio.h>
370#include <stdlib.h>
371#include <sys/ioctl.h>
372#include <unistd.h>
373
374int
375main(int argc, char *argv[])
376{
377 uint32_t id;
378 int fd;
379 int ret;
380
381 if (argc != 2) {
382 printf("Usage: %s FILENAME\\n", argv[0]);
383 exit(EXIT_FAILURE);
384 }
385
386 fd = open(argv[1], O_RDONLY);
387 if (fd == \-1) {
388 perror("open");
389 exit(EXIT_FAILURE);
390 }
391
392 /*
393 * Read volume ID.
394 */
395 ret = ioctl(fd, FAT_IOCTL_GET_VOLUME_ID, &id);
396 if (ret == \-1) {
397 perror("ioctl");
398 exit(EXIT_FAILURE);
399 }
400
401 /*
402 * Format the output as two groups of 16 bits each.
403 */
404 printf("Volume ID %4x\-%4x\\n", id >> 16, id & 0xFFFF);
405
406 close(fd);
407
3b4f9570 408 exit(EXIT_SUCCESS);
a1cd6a8f
HS
409}
410.fi
411.in
412.SS Listing a directory
f54da10e
MK
413The following program demonstrates the use of
414.BR ioctl (2)
415to list a directory.
a1cd6a8f 416.PP
f54da10e
MK
417The following was recorded when applying the program to the directory
418.IR /mnt/user :
419
a1cd6a8f
HS
420.in +4n
421.nf
422$ ./fat_dir /mnt/user
423\[char46] -> ''
424\[char46]. -> ''
425ALONGF~1.TXT -> 'a long filename.txt'
426UPPER.TXT -> ''
427LOWER.TXT -> 'lower.txt'
428.fi
429.in
430.SS Program source
431.in +4n
432.nf
433#include <fcntl.h>
434#include <linux/msdos_fs.h>
435#include <stdio.h>
436#include <stdlib.h>
437#include <sys/ioctl.h>
438#include <unistd.h>
439
440int
441main(int argc, char *argv[])
442{
443 struct __fat_dirent entry[2];
444 int fd;
445 int ret;
446
447 if (argc != 2) {
448 printf("Usage: %s DIRECTORY\\n", argv[0]);
449 exit(EXIT_FAILURE);
450 }
451
452 /*
453 * Open file descriptor for the directory.
454 */
455 fd = open(argv[1], O_RDONLY | O_DIRECTORY);
456 if (fd == \-1) {
457 perror("open");
458 exit(EXIT_FAILURE);
459 }
460
461 for (;;) {
462
463 /*
464 * Read next directory entry.
465 */
466 ret = ioctl( fd, VFAT_IOCTL_READDIR_BOTH, entry);
467
468 /*
469 * If an error occurs, the return value is \-1.
432cdf0d
HS
470 * If the end of the directory list has been reached,
471 * the return value is 0.
472 * For backward compatibility the end of the directory
473 * list is also signaled by d_reclen == 0.
a1cd6a8f 474 */
432cdf0d 475 if (ret < 1)
a1cd6a8f
HS
476 break;
477
478 /*
479 * Write both the short name and the long name.
480 */
481 printf("%s \-> '%s'\\n", entry[0].d_name, entry[1].d_name);
482 }
f54da10e 483
a1cd6a8f
HS
484 if (ret == \-1) {
485 perror("VFAT_IOCTL_READDIR_BOTH");
486 exit(EXIT_FAILURE);
487 }
488
489 /*
490 * Close the file descriptor.
491 */
492 close(fd);
493
3b4f9570 494 exit(EXIT_SUCCESS);
a1cd6a8f
HS
495}
496.fi
497.in
498.SH SEE ALSO
499.BR ioctl (2)