tree-wide: never use the off_t unless glibc makes us use it

off_t is a really weird type as it is usually 64bit these days (at least
in sane programs), but could theoretically be 32bit. We don't support
off_t as 32bit builds though, but still constantly deal with safely
converting from off_t to other types and back for no point.

Hence, never use the type anymore. Always use uint64_t instead. This has
various benefits, including that we can expose these values directly as
D-Bus properties, and also that the values parse the same in all cases.
This commit is contained in:
Lennart Poettering
2015-09-10 18:16:18 +02:00
parent f33be31198
commit 59f448cf15
31 changed files with 174 additions and 172 deletions
+8 -8
View File
@@ -29,7 +29,7 @@
#define COPY_BUFFER_SIZE (16*1024)
int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
bool try_sendfile = true, try_splice = true;
int r;
@@ -37,7 +37,7 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
assert(fdt >= 0);
/* Try btrfs reflinks first. */
if (try_reflink && max_bytes == (off_t) -1) {
if (try_reflink && max_bytes == (uint64_t) -1) {
r = btrfs_reflink(fdf, fdt);
if (r >= 0)
return r;
@@ -47,12 +47,12 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
size_t m = COPY_BUFFER_SIZE;
ssize_t n;
if (max_bytes != (off_t) -1) {
if (max_bytes != (uint64_t) -1) {
if (max_bytes <= 0)
return -EFBIG;
if ((off_t) m > max_bytes)
if ((uint64_t) m > max_bytes)
m = (size_t) max_bytes;
}
@@ -105,8 +105,8 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
}
next:
if (max_bytes != (off_t) -1) {
assert(max_bytes >= n);
if (max_bytes != (uint64_t) -1) {
assert(max_bytes >= (uint64_t) n);
max_bytes -= n;
}
}
@@ -152,7 +152,7 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int
if (fdt < 0)
return -errno;
r = copy_bytes(fdf, fdt, (off_t) -1, true);
r = copy_bytes(fdf, fdt, (uint64_t) -1, true);
if (r < 0) {
unlinkat(dt, to, 0);
return r;
@@ -371,7 +371,7 @@ int copy_file_fd(const char *from, int fdt, bool try_reflink) {
if (fdf < 0)
return -errno;
r = copy_bytes(fdf, fdt, (off_t) -1, try_reflink);
r = copy_bytes(fdf, fdt, (uint64_t) -1, try_reflink);
(void) copy_times(fdf, fdt);
(void) copy_xattr(fdf, fdt);
+2 -1
View File
@@ -21,6 +21,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include <inttypes.h>
#include <stdbool.h>
#include <sys/types.h>
@@ -30,6 +31,6 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace
int copy_tree(const char *from, const char *to, bool merge);
int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge);
int copy_directory_fd(int dirfd, const char *to, bool merge);
int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink);
int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink);
int copy_times(int fdf, int fdt);
int copy_xattr(int fdf, int fdt);
+45 -46
View File
@@ -2214,7 +2214,7 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
return 0;
}
int parse_size(const char *t, off_t base, off_t *size) {
int parse_size(const char *t, uint64_t base, uint64_t *size) {
/* Soo, sometimes we want to parse IEC binary suffixes, and
* sometimes SI decimal suffixes. This function can parse
@@ -2242,8 +2242,8 @@ int parse_size(const char *t, off_t base, off_t *size) {
{ "G", 1024ULL*1024ULL*1024ULL },
{ "M", 1024ULL*1024ULL },
{ "K", 1024ULL },
{ "B", 1 },
{ "", 1 },
{ "B", 1ULL },
{ "", 1ULL },
};
static const struct table si[] = {
@@ -2253,8 +2253,8 @@ int parse_size(const char *t, off_t base, off_t *size) {
{ "G", 1000ULL*1000ULL*1000ULL },
{ "M", 1000ULL*1000ULL },
{ "K", 1000ULL },
{ "B", 1 },
{ "", 1 },
{ "B", 1ULL },
{ "", 1ULL },
};
const struct table *table;
@@ -2276,33 +2276,32 @@ int parse_size(const char *t, off_t base, off_t *size) {
p = t;
do {
long long l;
unsigned long long l2;
unsigned long long l, tmp;
double frac = 0;
char *e;
unsigned i;
errno = 0;
l = strtoll(p, &e, 10);
if (errno > 0)
return -errno;
if (l < 0)
p += strspn(p, WHITESPACE);
if (*p == '-')
return -ERANGE;
errno = 0;
l = strtoull(p, &e, 10);
if (errno > 0)
return -errno;
if (e == p)
return -EINVAL;
if (*e == '.') {
e++;
/* strtoull() itself would accept space/+/- */
if (*e >= '0' && *e <= '9') {
unsigned long long l2;
char *e2;
/* strotoull itself would accept space/+/- */
l2 = strtoull(e, &e2, 10);
if (errno == ERANGE)
if (errno > 0)
return -errno;
/* Ignore failure. E.g. 10.M is valid */
@@ -2315,27 +2314,27 @@ int parse_size(const char *t, off_t base, off_t *size) {
e += strspn(e, WHITESPACE);
for (i = start_pos; i < n_entries; i++)
if (startswith(e, table[i].suffix)) {
unsigned long long tmp;
if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
return -ERANGE;
tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
if (tmp > ULLONG_MAX - r)
return -ERANGE;
r += tmp;
if ((unsigned long long) (off_t) r != r)
return -ERANGE;
p = e + strlen(table[i].suffix);
start_pos = i + 1;
if (startswith(e, table[i].suffix))
break;
}
if (i >= n_entries)
return -EINVAL;
if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
return -ERANGE;
tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
if (tmp > ULLONG_MAX - r)
return -ERANGE;
r += tmp;
if ((unsigned long long) (uint64_t) r != r)
return -ERANGE;
p = e + strlen(table[i].suffix);
start_pos = i + 1;
} while (*p);
*size = r;
@@ -3785,38 +3784,38 @@ int prot_from_flags(int flags) {
}
}
char *format_bytes(char *buf, size_t l, off_t t) {
char *format_bytes(char *buf, size_t l, uint64_t t) {
unsigned i;
static const struct {
const char *suffix;
off_t factor;
uint64_t factor;
} table[] = {
{ "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
{ "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
{ "T", 1024ULL*1024ULL*1024ULL*1024ULL },
{ "G", 1024ULL*1024ULL*1024ULL },
{ "M", 1024ULL*1024ULL },
{ "K", 1024ULL },
{ "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
{ "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
{ "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
{ "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
{ "M", UINT64_C(1024)*UINT64_C(1024) },
{ "K", UINT64_C(1024) },
};
if (t == (off_t) -1)
if (t == (uint64_t) -1)
return NULL;
for (i = 0; i < ELEMENTSOF(table); i++) {
if (t >= table[i].factor) {
snprintf(buf, l,
"%llu.%llu%s",
(unsigned long long) (t / table[i].factor),
(unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
"%" PRIu64 ".%" PRIu64 "%s",
t / table[i].factor,
((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
table[i].suffix);
goto finish;
}
}
snprintf(buf, l, "%lluB", (unsigned long long) t);
snprintf(buf, l, "%" PRIu64 "B", t);
finish:
buf[l-1] = 0;
+2 -2
View File
@@ -152,7 +152,7 @@ void close_many(const int fds[], unsigned n_fd);
int fclose_nointr(FILE *f);
FILE* safe_fclose(FILE *f);
int parse_size(const char *t, off_t base, off_t *size);
int parse_size(const char *t, uint64_t base, uint64_t *size);
int parse_boolean(const char *v) _pure_;
int parse_pid(const char *s, pid_t* ret_pid);
@@ -478,7 +478,7 @@ bool kexec_loaded(void);
int prot_from_flags(int flags) _const_;
char *format_bytes(char *buf, size_t l, off_t t);
char *format_bytes(char *buf, size_t l, uint64_t t);
int fd_wait_for_event(int fd, int event, usec_t timeout);