diff options
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/Kbuild | 1 | ||||
-rw-r--r-- | libbb/get_volsize.c | 48 |
2 files changed, 49 insertions, 0 deletions
diff --git a/libbb/Kbuild b/libbb/Kbuild index 7e79310..c205ceb 100644 --- a/libbb/Kbuild +++ b/libbb/Kbuild @@ -42,6 +42,7 @@ lib-y += get_last_path_component.o lib-y += get_line_from_file.o lib-y += getopt32.o lib-y += getpty.o +lib-y += get_volsize.o lib-y += herror_msg.o lib-y += herror_msg_and_die.o lib-y += human_readable.o diff --git a/libbb/get_volsize.c b/libbb/get_volsize.c new file mode 100644 index 0000000..5b02709 --- /dev/null +++ b/libbb/get_volsize.c @@ -0,0 +1,48 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Copyright (C) 2010 Denys Vlasenko + * + * Licensed under GPLv2, see file LICENSE in this tarball for details. + */ +#include "libbb.h" + +uoff_t FAST_FUNC get_volume_size_in_bytes(int fd, + const char *override, + unsigned override_units, + int extend) +{ + uoff_t result; + + if (override) { + result = XATOOFF(override); + if (result >= (uoff_t)(MAXINT(off_t)) / override_units) + bb_error_msg_and_die("image size is too big"); + result *= override_units; + /* seek past end fails on block devices but works on files */ + if (lseek(fd, result - 1, SEEK_SET) != (off_t)-1) { + if (extend) + xwrite(fd, "", 1); /* file grows if needed */ + } + //else { + // bb_error_msg("warning, block device is smaller"); + //} + } else { + /* more portable than BLKGETSIZE[64] */ + result = xlseek(fd, 0, SEEK_END); + } + + xlseek(fd, 0, SEEK_SET); + + /* Prevent things like this: + * $ dd if=/dev/zero of=foo count=1 bs=1024 + * $ mkswap foo + * Setting up swapspace version 1, size = 18446744073709548544 bytes + * + * Picked 16k arbitrarily: */ + if (result < 16*1024) + bb_error_msg_and_die("image is too small"); + + return result; +} |