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