re-mark 1.29b-2 as not yet uploaded (merge madness!)
[debian/tar] / tests / checkseekhole.c
1 /* Test suite for GNU tar - SEEK_HOLE detector.
2
3    Copyright 2015-2016 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 }