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