diff options
Diffstat (limited to 'fadvise.c')
-rw-r--r-- | fadvise.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/fadvise.c b/fadvise.c new file mode 100644 index 0000000..c2392f4 --- /dev/null +++ b/fadvise.c @@ -0,0 +1,102 @@ +#include "compat-util.h" + +static struct fa_advice { + const char *name; + const int nr; +} advice_table[] = { + { "normal", POSIX_FADV_NORMAL }, + { "sequential", POSIX_FADV_SEQUENTIAL }, + { "random", POSIX_FADV_RANDOM }, + { "noreuse", POSIX_FADV_NOREUSE }, + { "willneed", POSIX_FADV_WILLNEED }, + { "dontneed" , POSIX_FADV_DONTNEED } +}; + +static void apply_fadvise(const char *path, off_t offset, off_t len, int advice) +{ + int fd; + + if ((fd = open(path, O_RDONLY)) < 0) { + fprintf(stderr, "%s: open(): %s\n", path, strerror(errno)); + return; + } + + if (len <= 0) { + /* for compatibility with kernels < 2.6.6 */ + struct stat sb; + + if (fstat(fd, &sb) < 0) { + fprintf(stderr, "%s: fstat(%d): %s\n", + path, fd, strerror(errno)); + goto out; + } + len = sb.st_size; + } + + if (posix_fadvise(fd, offset, len, advice) < 0) + fprintf(stderr, + "%s: posix_fadvise(" + "offset=%lu,len=%lu,advice=%d): %s\n", + path, + (unsigned long)offset, + (unsigned long)len, + advice, strerror(errno)); + +out: + close(fd); +} + +int main(int argc, char * const argv[]) +{ + off_t offset = 0; + off_t len = 0; + int advice = POSIX_FADV_NORMAL; + int opt; + int argi = 1; + + while ((opt = getopt(argc, argv, "o:l:a:")) != -1) { + int i; + char *err; + + argi += 2; + switch(opt) { + case 'o': + offset = strtol(optarg, &err, 10); + if (*err || offset < 0) { + fprintf(stderr, "offset must be >= 0\n"); + return 1; + } + break; + case 'l': + len = strtol(optarg, &err, 10); + if (*err || len < 0) { + fprintf(stderr, "length must be >= 0\n"); + return 1; + } + break; + case 'a': + for (i = 0; i < ARRAY_SIZE(advice_table); ++i) { + if (strcmp(advice_table[i].name, optarg)) + continue; + advice = advice_table[i].nr; + break; + } + if (i < ARRAY_SIZE(advice_table)) + break; + fprintf(stderr, "advice '%s' not understood\n", optarg); + /* fall-through */ + default: + fprintf(stderr, + "Usage: %s [-a advice] [-o offset] " + "[-l length] <files>\n", argv[0]); + fprintf(stderr, "\nPossible values for advice:\n"); + for (i = 0; i < ARRAY_SIZE(advice_table); ++i) + fprintf(stderr, "\t%s\n", advice_table[i].name); + return 1; + } + } + + for (; argi < argc; ++argi) + apply_fadvise(argv[argi], offset, len, advice); + return 0; +} |