pcu.git  about / heads / tags
page cache utilities for Linux
blob c2392f42511320e594ea51979c0eef2c89ae407f 2266 bytes (raw)
$ git show v0.1.0:fadvise.c	# shows this blob on the CLI

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
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;
}

git clone https://yhbt.net/pcu.git