checkseekhole.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /* Test suite for GNU tar - SEEK_HOLE detector.
  2. Copyright 2015-2023 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify it
  4. under the terms of the GNU General Public License as published by the
  5. Free Software Foundation; either version 3, or (at your option) any later
  6. version.
  7. This program is distributed in the hope that it will be useful, but
  8. WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  10. Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with this program. If not, see <http://www.gnu.org/licenses/>.
  13. Description: detect whether it is possible to work with SEEK_HOLE on
  14. particular operating system and file system. */
  15. #include "config.h"
  16. #include <sys/stat.h>
  17. #include <sys/types.h>
  18. #include <unistd.h>
  19. #include <stdlib.h>
  20. #include <fcntl.h>
  21. enum {
  22. EX_OK = 0, /* SEEK_HOLE support */
  23. EX_FAIL, /* test failed - no SEEK_HOLE support */
  24. EX_BAD, /* test is not relevant */
  25. };
  26. int
  27. check_seek_hole (int fd)
  28. {
  29. #ifdef SEEK_HOLE
  30. struct stat stat;
  31. off_t offset;
  32. /* hole of 100MB */
  33. if (lseek (fd, 100*1024*1024, SEEK_END) < 0)
  34. return EX_BAD;
  35. /* piece of data */
  36. if (write (fd, "data\n", 5) != 5)
  37. return EX_BAD;
  38. /* another hole */
  39. if (lseek (fd, 100*1024*1024, SEEK_END) < 0)
  40. return EX_BAD;
  41. /* piece of data */
  42. if (write (fd, "data\n", 5) != 5)
  43. return EX_BAD;
  44. if (fstat (fd, &stat))
  45. return EX_BAD;
  46. offset = lseek (fd, 0, SEEK_DATA);
  47. if (offset == (off_t)-1)
  48. return EX_FAIL;
  49. offset = lseek (fd, offset, SEEK_HOLE);
  50. if (offset == (off_t)-1 || offset == stat.st_size)
  51. return EX_FAIL;
  52. return EX_OK;
  53. #else
  54. return EX_BAD;
  55. #endif
  56. }
  57. int
  58. main ()
  59. {
  60. #ifdef SEEK_HOLE
  61. int rc;
  62. char template[] = "testseekhole-XXXXXX";
  63. int fd = mkstemp (template);
  64. if (fd == -1)
  65. return EX_BAD;
  66. rc = check_seek_hole (fd);
  67. close (fd);
  68. unlink (template);
  69. return rc;
  70. #else
  71. return EX_FAIL;
  72. #endif
  73. }