From 8b4ebef131656614386878692a07f8c51e533a8a Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 9 May 2009 21:16:23 -0700 Subject: mincore: allow offset and length to be specified Users won't have to mmap entire files if they don't want to --- mincore.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/mincore.c b/mincore.c index 6b8b0e2..81a1262 100644 --- a/mincore.c +++ b/mincore.c @@ -1,12 +1,12 @@ #include "compat-util.h" -static void mincore_stats(const char *path) +static void mincore_stats(const char *path, off_t offset, off_t len) { - struct stat sb; char *map; unsigned char *vec; size_t vec_len; size_t map_len; + off_t map_offset; int fd; size_t i; static const char *fmt = sizeof(void *) == 8 ? @@ -17,21 +17,29 @@ static void mincore_stats(const char *path) return; } - if (fstat(fd, &sb) < 0) { - fprintf(stderr, "%s: fstat(%d): %s\n", - path, fd, strerror(errno)); - goto err_close; + if (!len) { + struct stat sb; + + if (fstat(fd, &sb) < 0) { + fprintf(stderr, "%s: fstat(%d): %s\n", + path, fd, strerror(errno)); + goto err_close; + } + len = sb.st_size; } - vec_len = (sb.st_size + page_size() - 1) / page_size(); + vec_len = (len + page_size() - 1) / page_size(); if (!(vec = malloc(vec_len))) { fprintf(stderr, "%s: malloc(%lu): %s\n", path, (unsigned long)vec_len, strerror(errno)); goto err_close; } - map_len = PAGE_ALIGN(sb.st_size); - if (!(map = mmap(NULL, map_len, PROT_READ, MAP_SHARED, fd, 0))) { + map_len = PAGE_ALIGN(len); + map_offset = PAGE_ALIGN_DOWN(offset); + + map = mmap(NULL, map_len, PROT_READ, MAP_SHARED, fd, map_offset); + if (!map) { fprintf(stderr, "%s: mmap(%lu): %s\n", path, (unsigned long)vec_len, strerror(errno)); goto err_free; @@ -44,7 +52,9 @@ static void mincore_stats(const char *path) } for (i = 0; i < vec_len; ++i) - printf(fmt, path, (unsigned long)(page_size() * i), vec[i]); + printf(fmt, path, + (unsigned long)(page_size() * i) + map_offset, + vec[i]); err_munmap: munmap(map, map_len); err_free: @@ -55,9 +65,39 @@ err_close: int main(int argc, char * const argv[]) { - int i; + off_t offset = 0; + off_t len = 0; + int argi = 1; + int opt; + + while ((opt = getopt(argc, argv, "o:l:")) != -1) { + 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; + default: + fprintf(stderr, + "Usage: %s [-o offset] " + "[-l length] \n", argv[0]); + return 1; + } + } - for (i = 1; i < argc; ++i) - mincore_stats(argv[i]); + for (; argi < argc; ++argi) + mincore_stats(argv[argi], offset, len); return 0; } -- cgit v1.2.3-24-ge0c7