From: Eric Wong Date: Sat, 1 Aug 2009 18:34:00 +0000 (-0700) Subject: More accurate string => off_t conversion X-Git-Tag: v0.2.1~2 X-Git-Url: https://repo.or.cz/w/pcu.git/commitdiff_plain/1ca0715f4bf2bb98cda7b8c5b80a2ce51e9f1473 More accurate string => off_t conversion off_t can either be 32-bits or 64-bits wide on popular architectures in 2009, so we need to pick between strtol and strtoll. This allows us to (hopefully) deal with files larger than 2G on 32-bit machines --- diff --git a/compat-util.h b/compat-util.h index 60c4081..8b70b52 100644 --- a/compat-util.h +++ b/compat-util.h @@ -15,6 +15,7 @@ #include #include #include +#include #ifndef O_NOATIME # define O_NOATIME 0 @@ -37,4 +38,21 @@ static inline size_t page_size(void) #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +/* + * converts a C string to a non-negative off_t value, taking base into + * account. On error, it'll return a negative value and set errno + * to EINVAL + */ +static off_t cstr_to_off_t(const char *nptr, char **endptr, int base) +{ + if (sizeof(long) == 8 || (sizeof(long) == 4 && sizeof(off_t) == 4)) + return (off_t)strtol(nptr, endptr, base); + else if (sizeof(off_t) == 8 && sizeof(long) == 4) + return (off_t)strtoll(nptr, endptr, base); + + fprintf(stderr, "unrecognized sizes:\n\toff_t: %u\n\tlong: %u\n", + sizeof(off_t), sizeof(long)); + exit(1); +} + #endif /* OS_COMPAT_H */ diff --git a/fadvise.c b/fadvise.c index ddc07fb..12c9b1b 100644 --- a/fadvise.c +++ b/fadvise.c @@ -75,14 +75,14 @@ int main(int argc, char * const argv[]) argi += 2; switch(opt) { case 'o': - offset = strtol(optarg, &err, 10); + offset = cstr_to_off_t(optarg, &err, 10); if (*err || offset < 0) { fprintf(stderr, "offset must be >= 0\n"); return 1; } break; case 'l': - len = strtol(optarg, &err, 10); + len = cstr_to_off_t(optarg, &err, 10); if (*err || len < 0) { fprintf(stderr, "length must be >= 0\n"); return 1; diff --git a/mincore.c b/mincore.c index 2e26582..c3aa618 100644 --- a/mincore.c +++ b/mincore.c @@ -82,14 +82,14 @@ int main(int argc, char * const argv[]) argi += 2; switch(opt) { case 'o': - offset = strtol(optarg, &err, 10); + offset = cstr_to_off_t(optarg, &err, 10); if (*err || offset < 0) { fprintf(stderr, "offset must be >= 0\n"); return 1; } break; case 'l': - len = strtol(optarg, &err, 10); + len = cstr_to_off_t(optarg, &err, 10); if (*err || len < 0) { fprintf(stderr, "length must be >= 0\n"); return 1;