get_volsize.c 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Utility routines.
  4. *
  5. * Copyright (C) 2010 Denys Vlasenko
  6. *
  7. * Licensed under GPLv2, see file LICENSE in this source tree.
  8. */
  9. #include "libbb.h"
  10. uoff_t FAST_FUNC get_volume_size_in_bytes(int fd,
  11. const char *override,
  12. unsigned override_units,
  13. int extend)
  14. {
  15. uoff_t result;
  16. if (override) {
  17. result = XATOOFF(override);
  18. if (result >= (uoff_t)(MAXINT(off_t)) / override_units)
  19. bb_simple_error_msg_and_die("image size is too big");
  20. result *= override_units;
  21. /* seek past end fails on block devices but works on files */
  22. if (lseek(fd, result - 1, SEEK_SET) != (off_t)-1) {
  23. if (extend)
  24. xwrite(fd, "", 1); /* file grows if needed */
  25. }
  26. //else {
  27. // bb_error_msg("warning, block device is smaller");
  28. //}
  29. } else {
  30. /* more portable than BLKGETSIZE[64] */
  31. result = xlseek(fd, 0, SEEK_END);
  32. }
  33. xlseek(fd, 0, SEEK_SET);
  34. /* Prevent things like this:
  35. * $ dd if=/dev/zero of=foo count=1 bs=1024
  36. * $ mkswap foo
  37. * Setting up swapspace version 1, size = 18446744073709548544 bytes
  38. *
  39. * Picked 16k arbitrarily: */
  40. if (result < 16*1024)
  41. bb_simple_error_msg_and_die("image is too small");
  42. return result;
  43. }