2 * fadvise - utility to use the posix_fadvise(2)
4 * Copyright (C) 2022 Red Hat, Inc. All rights reserved.
5 * Written by Masatake YAMATO <yamato@redhat.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it would be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 static const struct advice
{
35 { "normal", POSIX_FADV_NORMAL
, },
36 { "sequential", POSIX_FADV_SEQUENTIAL
, },
37 { "random", POSIX_FADV_RANDOM
, },
38 { "noreuse", POSIX_FADV_NOREUSE
, },
39 { "willneeded", POSIX_FADV_WILLNEED
, },
40 { "dontneed", POSIX_FADV_DONTNEED
, },
43 static void __attribute__((__noreturn__
)) usage(void)
48 fputs(USAGE_HEADER
, out
);
49 fprintf(out
, _(" %s [options] file\n"), program_invocation_short_name
);
50 fprintf(out
, _(" %s [options] --fd|-d file-descriptor\n"), program_invocation_short_name
);
52 fputs(USAGE_OPTIONS
, out
);
53 fputs(_(" -a, --advice <advice> applying advice to the file (default: \"dontneed\")\n"), out
);
54 fputs(_(" -l, --length <num> length for range operations, in bytes\n"), out
);
55 fputs(_(" -o, --offset <num> offset for range operations, in bytes\n"), out
);
57 fputs(USAGE_SEPARATOR
, out
);
58 fprintf(out
, USAGE_HELP_OPTIONS(23));
60 fputs(_("\nAvailable values for advice:\n"), out
);
61 for (i
= 0; i
< ARRAY_SIZE(advices
); i
++) {
66 fprintf(out
, USAGE_MAN_TAIL("fadvise(1)"));
71 int main(int argc
, char ** argv
)
75 bool do_close
= false;
80 int advice
= POSIX_FADV_DONTNEED
;
82 static const struct option longopts
[] = {
83 { "advice", required_argument
, NULL
, 'a' },
84 { "fd", required_argument
, NULL
, 'd' },
85 { "length", required_argument
, NULL
, 'l' },
86 { "offset", required_argument
, NULL
, 'o' },
87 { "version", no_argument
, NULL
, 'V' },
88 { "help", no_argument
, NULL
, 'h' },
92 setlocale(LC_ALL
, "");
93 bindtextdomain(PACKAGE
, LOCALEDIR
);
96 while ((c
= getopt_long (argc
, argv
, "a:d:hl:o:V", longopts
, NULL
)) != -1) {
100 for (size_t i
= 0; i
< ARRAY_SIZE(advices
); i
++) {
101 if (strcmp(optarg
, advices
[i
].name
) == 0) {
102 advice
= advices
[i
].num
;
107 errx(EXIT_FAILURE
, "invalid advice argument: '%s'", optarg
);
110 fd
= strtos32_or_err(optarg
,
111 _("invalid fd argument"));
114 len
= strtosize_or_err(optarg
,
115 _("invalid length argument"));
118 offset
= strtosize_or_err(optarg
,
119 _("invalid offset argument"));
122 print_version(EXIT_SUCCESS
);
126 errtryhelp(EXIT_FAILURE
);
130 if (optind
== argc
&& fd
== -1) {
131 warnx(_("no file specified"));
132 errtryhelp(EXIT_FAILURE
);
135 if (argc
- optind
> 0 && fd
!= -1) {
136 warnx(_("specify either file descriptor or file name"));
137 errtryhelp(EXIT_FAILURE
);
140 if (argc
- optind
> 1) {
141 warnx(_("specify one file descriptor or file name"));
142 errtryhelp(EXIT_FAILURE
);
146 fd
= open(argv
[optind
], O_RDONLY
);
148 err(EXIT_FAILURE
, _("cannot open %s"), argv
[optind
]);
152 rc
= posix_fadvise(fd
,
156 warnx(_("failed to advise: %s"), strerror(rc
));
161 return rc
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;