xref: /freebsd/tools/test/stress2/tools/lsholes.c (revision f126890a)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/param.h>
29 #include <sys/stat.h>
30 
31 #include <err.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 
38 int
39 main(int argc, char *argv[])
40 {
41 	struct stat st;
42 	off_t data, hole, pos;
43 	long mn;
44 	intmax_t siz;
45 	int fd, n;
46 	char *name;
47 
48         if (argc != 2) {
49                 fprintf(stderr, "Usage: %s <file>\n", argv[0]);
50                 exit(1);
51         }
52 
53         name = argv[1];
54         if ((fd = open(name, O_RDONLY)) == -1)
55                 err(1, "open(%s)", name);
56         if (fstat(fd, &st))
57                 err(1, "fstat()");
58 	if ((mn = fpathconf(fd, _PC_MIN_HOLE_SIZE)) == -1)
59 		err(1, "fpathconf()");
60 	fprintf(stderr, "Min hole size is %ld, file size is %jd.\n",
61 	    mn, (intmax_t)st.st_size);
62 	n = 1;
63 	pos = 0;
64 
65 	while (pos < st.st_size) {
66 		hole = lseek(fd, pos, SEEK_HOLE);
67 		if (hole == -1 && errno != ENXIO)
68 			err(1, "lseek(SEEK_HOLE)");
69 		data = lseek(fd, pos, SEEK_DATA);
70 		if (data == -1 && errno != ENXIO)
71 			err(1, "lseek(SEEK_data)");
72 
73 		if (hole >= 0 && data >= 0 && hole > data) {
74 			siz = hole - data;
75 			printf("data #%d @ %ld, size=%jd)\n",
76 			    n, (intmax_t)data, siz);
77 			n++;
78 			pos += siz;
79 		}
80 		if (hole >= 0 && data >= 0 && hole < data) {
81 			siz = data - hole;
82 			printf("hole #%d @ %ld, size=%jd\n",
83 			    n, (intmax_t)hole, siz);
84 			n++;
85 			pos += siz;
86 		}
87 		if (hole >= 0 && data == -1) {
88 			siz = st.st_size - hole;
89 			printf("hole #%d @ %ld, size=%jd\n",
90 			    n, (intmax_t)hole, siz);
91 			n++;
92 			pos += siz;
93 		}
94         }
95 	if (hole == st.st_size) {
96 		/* EOF */
97 		printf("hole #%d @ %ld, size=%jd\n",
98 		    n, (intmax_t)hole, 0L);
99 	}
100         close(fd);
101 }
102