xref: /illumos-gate/usr/src/test/os-tests/tests/hexdump/hexdump_basic.c (revision 43379a280422204006ceee5a5c5380444cb515d9)
1*43379a28SAndy Fiddaman /*
2*43379a28SAndy Fiddaman  * This file and its contents are supplied under the terms of the
3*43379a28SAndy Fiddaman  * Common Development and Distribution License ("CDDL"), version 1.0.
4*43379a28SAndy Fiddaman  * You may only use this file in accordance with the terms of version
5*43379a28SAndy Fiddaman  * 1.0 of the CDDL.
6*43379a28SAndy Fiddaman  *
7*43379a28SAndy Fiddaman  * A full copy of the text of the CDDL should have accompanied this
8*43379a28SAndy Fiddaman  * source.  A copy of the CDDL is also available via the Internet at
9*43379a28SAndy Fiddaman  * http://www.illumos.org/license/CDDL.
10*43379a28SAndy Fiddaman  */
11*43379a28SAndy Fiddaman 
12*43379a28SAndy Fiddaman /*
13*43379a28SAndy Fiddaman  * Copyright 2024 Oxide Computer Company
14*43379a28SAndy Fiddaman  */
15*43379a28SAndy Fiddaman 
16*43379a28SAndy Fiddaman /*
17*43379a28SAndy Fiddaman  * Basic tests for the common hexdump routine.
18*43379a28SAndy Fiddaman  */
19*43379a28SAndy Fiddaman 
20*43379a28SAndy Fiddaman #include <err.h>
21*43379a28SAndy Fiddaman #include <errno.h>
22*43379a28SAndy Fiddaman #include <fcntl.h>
23*43379a28SAndy Fiddaman #include <stdio.h>
24*43379a28SAndy Fiddaman #include <stdlib.h>
25*43379a28SAndy Fiddaman #include <string.h>
26*43379a28SAndy Fiddaman #include <strings.h>
27*43379a28SAndy Fiddaman #include <unistd.h>
28*43379a28SAndy Fiddaman #include <sys/debug.h>
29*43379a28SAndy Fiddaman #include <sys/ilstr.h>
30*43379a28SAndy Fiddaman #include <sys/hexdump.h>
31*43379a28SAndy Fiddaman #include <sys/mman.h>
32*43379a28SAndy Fiddaman #include <sys/stat.h>
33*43379a28SAndy Fiddaman #include <sys/stdbool.h>
34*43379a28SAndy Fiddaman #include <sys/sysmacros.h>
35*43379a28SAndy Fiddaman #include <sys/types.h>
36*43379a28SAndy Fiddaman 
37*43379a28SAndy Fiddaman #define	DATADIR	"/opt/os-tests/tests/hexdump/data"
38*43379a28SAndy Fiddaman 
39*43379a28SAndy Fiddaman const char *
_umem_debug_init(void)40*43379a28SAndy Fiddaman _umem_debug_init(void)
41*43379a28SAndy Fiddaman {
42*43379a28SAndy Fiddaman 	return ("default,verbose");
43*43379a28SAndy Fiddaman }
44*43379a28SAndy Fiddaman 
45*43379a28SAndy Fiddaman const char *
_umem_logging_init(void)46*43379a28SAndy Fiddaman _umem_logging_init(void)
47*43379a28SAndy Fiddaman {
48*43379a28SAndy Fiddaman 	return ("transaction,contents,fail");
49*43379a28SAndy Fiddaman }
50*43379a28SAndy Fiddaman 
51*43379a28SAndy Fiddaman typedef struct test {
52*43379a28SAndy Fiddaman 	const char		*name;
53*43379a28SAndy Fiddaman 	hexdump_flag_t		flags;
54*43379a28SAndy Fiddaman 	uint8_t			width;
55*43379a28SAndy Fiddaman 	uint8_t			grouping;
56*43379a28SAndy Fiddaman 	uint64_t		addr;
57*43379a28SAndy Fiddaman 	uint8_t			indent;
58*43379a28SAndy Fiddaman 	uint8_t			marker;
59*43379a28SAndy Fiddaman } test_t;
60*43379a28SAndy Fiddaman 
61*43379a28SAndy Fiddaman test_t tests[] = {
62*43379a28SAndy Fiddaman 	{
63*43379a28SAndy Fiddaman 		.name = "basic",
64*43379a28SAndy Fiddaman 	}, {
65*43379a28SAndy Fiddaman 		.name = "header",
66*43379a28SAndy Fiddaman 		.flags = HDF_HEADER,
67*43379a28SAndy Fiddaman 	}, {
68*43379a28SAndy Fiddaman 		.name = "address",
69*43379a28SAndy Fiddaman 		.flags = HDF_ADDRESS,
70*43379a28SAndy Fiddaman 	}, {
71*43379a28SAndy Fiddaman 		.name = "ascii",
72*43379a28SAndy Fiddaman 		.flags = HDF_ASCII,
73*43379a28SAndy Fiddaman 	}, {
74*43379a28SAndy Fiddaman 		.name = "dedup",
75*43379a28SAndy Fiddaman 		.flags = HDF_DEDUP,
76*43379a28SAndy Fiddaman 	}, {
77*43379a28SAndy Fiddaman 		.name = "doublespace",
78*43379a28SAndy Fiddaman 		.flags = HDF_DOUBLESPACE,
79*43379a28SAndy Fiddaman 	}, {
80*43379a28SAndy Fiddaman 		.name = "address+header",
81*43379a28SAndy Fiddaman 		.flags = HDF_ADDRESS | HDF_HEADER,
82*43379a28SAndy Fiddaman 	}, {
83*43379a28SAndy Fiddaman 		.name = "default",
84*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT,
85*43379a28SAndy Fiddaman 	}, {
86*43379a28SAndy Fiddaman 		.name = "marker1",
87*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DEDUP,
88*43379a28SAndy Fiddaman 		.marker = 5
89*43379a28SAndy Fiddaman 	}, {
90*43379a28SAndy Fiddaman 		.name = "addr1",
91*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DEDUP,
92*43379a28SAndy Fiddaman 		.addr = 0x876543
93*43379a28SAndy Fiddaman 	}, {
94*43379a28SAndy Fiddaman 		.name = "addr2",
95*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DEDUP,
96*43379a28SAndy Fiddaman 		.addr = 0xffff8
97*43379a28SAndy Fiddaman 	}, {
98*43379a28SAndy Fiddaman 		.name = "align1",
99*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DEDUP | HDF_ALIGN,
100*43379a28SAndy Fiddaman 		.addr = 0x876543
101*43379a28SAndy Fiddaman 	}, {
102*43379a28SAndy Fiddaman 		.name = "indent",
103*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DEDUP,
104*43379a28SAndy Fiddaman 		.indent = 3
105*43379a28SAndy Fiddaman 	}, {
106*43379a28SAndy Fiddaman 		.name = "group2",
107*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DEDUP,
108*43379a28SAndy Fiddaman 		.addr = 0x876543,
109*43379a28SAndy Fiddaman 		.grouping = 2,
110*43379a28SAndy Fiddaman 	}, {
111*43379a28SAndy Fiddaman 		.name = "group4",
112*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DEDUP,
113*43379a28SAndy Fiddaman 		.addr = 0x876543,
114*43379a28SAndy Fiddaman 		.grouping = 4,
115*43379a28SAndy Fiddaman 	}, {
116*43379a28SAndy Fiddaman 		.name = "group8",
117*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DEDUP,
118*43379a28SAndy Fiddaman 		.addr = 0x876543,
119*43379a28SAndy Fiddaman 		.grouping = 8,
120*43379a28SAndy Fiddaman 	}, {
121*43379a28SAndy Fiddaman 		.name = "width12",
122*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DEDUP,
123*43379a28SAndy Fiddaman 		.addr = 0x876543,
124*43379a28SAndy Fiddaman 		.width = 12,
125*43379a28SAndy Fiddaman 		.grouping = 4
126*43379a28SAndy Fiddaman 	}, {
127*43379a28SAndy Fiddaman 		.name = "wide1",
128*43379a28SAndy Fiddaman 		.flags = HDF_ADDRESS | HDF_HEADER,
129*43379a28SAndy Fiddaman 		.addr = 0x876543,
130*43379a28SAndy Fiddaman 		.width = 32,
131*43379a28SAndy Fiddaman 		.grouping = 8
132*43379a28SAndy Fiddaman 	}, {
133*43379a28SAndy Fiddaman 		.name = "narrow1",
134*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DOUBLESPACE,
135*43379a28SAndy Fiddaman 		.addr = 0x876543,
136*43379a28SAndy Fiddaman 		.width = 4,
137*43379a28SAndy Fiddaman 		.grouping = 2
138*43379a28SAndy Fiddaman 	}, {
139*43379a28SAndy Fiddaman 		.name = "narrow2",
140*43379a28SAndy Fiddaman 		.flags = HDF_DEFAULT | HDF_DEDUP,
141*43379a28SAndy Fiddaman 		.addr = 0x876543,
142*43379a28SAndy Fiddaman 		.width = 1,
143*43379a28SAndy Fiddaman 		.grouping = 1
144*43379a28SAndy Fiddaman 	}
145*43379a28SAndy Fiddaman };
146*43379a28SAndy Fiddaman 
147*43379a28SAndy Fiddaman static char *flagdescr[] = {
148*43379a28SAndy Fiddaman 	"HEADER",
149*43379a28SAndy Fiddaman 	"ADDRESS",
150*43379a28SAndy Fiddaman 	"ASCII",
151*43379a28SAndy Fiddaman 	"ALIGN",
152*43379a28SAndy Fiddaman 	"DEDUP",
153*43379a28SAndy Fiddaman 	"DOUBLESPACE",
154*43379a28SAndy Fiddaman };
155*43379a28SAndy Fiddaman 
156*43379a28SAndy Fiddaman static void
descr(test_t * t,ilstr_t * i)157*43379a28SAndy Fiddaman descr(test_t *t, ilstr_t *i)
158*43379a28SAndy Fiddaman {
159*43379a28SAndy Fiddaman 	ilstr_append_str(i, "=============================================\n");
160*43379a28SAndy Fiddaman 	ilstr_aprintf(i, "[%s] w=%u g=%u a=0x%x - ",
161*43379a28SAndy Fiddaman 	    t->name, t->width, t->grouping, t->addr);
162*43379a28SAndy Fiddaman 
163*43379a28SAndy Fiddaman 	int flags = t->flags;
164*43379a28SAndy Fiddaman 	bool first = true;
165*43379a28SAndy Fiddaman 	while (flags != 0) {
166*43379a28SAndy Fiddaman 		int b = fls(flags);
167*43379a28SAndy Fiddaman 		if (b == 0)
168*43379a28SAndy Fiddaman 			break;
169*43379a28SAndy Fiddaman 		b--;
170*43379a28SAndy Fiddaman 		VERIFY3S(b, <, ARRAY_SIZE(flagdescr));
171*43379a28SAndy Fiddaman 		if (first)
172*43379a28SAndy Fiddaman 			first = false;
173*43379a28SAndy Fiddaman 		else
174*43379a28SAndy Fiddaman 			ilstr_append_char(i, ' ');
175*43379a28SAndy Fiddaman 		ilstr_aprintf(i, "%s", flagdescr[b]);
176*43379a28SAndy Fiddaman 		flags &= ~(1<< b);
177*43379a28SAndy Fiddaman 	}
178*43379a28SAndy Fiddaman 	ilstr_append_char(i, '\n');
179*43379a28SAndy Fiddaman 	ilstr_append_str(i, "=============================================\n");
180*43379a28SAndy Fiddaman }
181*43379a28SAndy Fiddaman 
182*43379a28SAndy Fiddaman static int
cb(void * arg,uint64_t addr __unused,const char * str,size_t l)183*43379a28SAndy Fiddaman cb(void *arg, uint64_t addr __unused, const char *str, size_t l)
184*43379a28SAndy Fiddaman {
185*43379a28SAndy Fiddaman 	ilstr_t *i = arg;
186*43379a28SAndy Fiddaman 
187*43379a28SAndy Fiddaman 	ilstr_append_str(i, str);
188*43379a28SAndy Fiddaman 	ilstr_append_char(i, '\n');
189*43379a28SAndy Fiddaman 
190*43379a28SAndy Fiddaman 	return (0);
191*43379a28SAndy Fiddaman }
192*43379a28SAndy Fiddaman 
193*43379a28SAndy Fiddaman static void
run(test_t * t,uint8_t * data,size_t len,ilstr_t * i)194*43379a28SAndy Fiddaman run(test_t *t, uint8_t *data, size_t len, ilstr_t *i)
195*43379a28SAndy Fiddaman {
196*43379a28SAndy Fiddaman 	hexdump_t hd;
197*43379a28SAndy Fiddaman 
198*43379a28SAndy Fiddaman 	descr(t, i);
199*43379a28SAndy Fiddaman 
200*43379a28SAndy Fiddaman 	hexdump_init(&hd);
201*43379a28SAndy Fiddaman 	if (t->width != 0)
202*43379a28SAndy Fiddaman 		hexdump_set_width(&hd, t->width);
203*43379a28SAndy Fiddaman 	if (t->grouping != 0)
204*43379a28SAndy Fiddaman 		hexdump_set_grouping(&hd, t->grouping);
205*43379a28SAndy Fiddaman 	if (t->addr != 0)
206*43379a28SAndy Fiddaman 		hexdump_set_addr(&hd, t->addr);
207*43379a28SAndy Fiddaman 	if (t->indent != 0)
208*43379a28SAndy Fiddaman 		hexdump_set_indent(&hd, t->indent);
209*43379a28SAndy Fiddaman 	if (t->marker != 0)
210*43379a28SAndy Fiddaman 		hexdump_set_marker(&hd, t->marker);
211*43379a28SAndy Fiddaman 
212*43379a28SAndy Fiddaman 	VERIFY0(hexdumph(&hd, data, len, t->flags, cb, (void *)i));
213*43379a28SAndy Fiddaman 
214*43379a28SAndy Fiddaman 	hexdump_fini(&hd);
215*43379a28SAndy Fiddaman 
216*43379a28SAndy Fiddaman 	VERIFY3U(ilstr_errno(i), ==, ILSTR_ERROR_OK);
217*43379a28SAndy Fiddaman }
218*43379a28SAndy Fiddaman 
219*43379a28SAndy Fiddaman static uint8_t *
mapfile(const char * filename,size_t * lenp)220*43379a28SAndy Fiddaman mapfile(const char *filename, size_t *lenp)
221*43379a28SAndy Fiddaman {
222*43379a28SAndy Fiddaman 	uint8_t *p;
223*43379a28SAndy Fiddaman 	struct stat st;
224*43379a28SAndy Fiddaman 	int fd;
225*43379a28SAndy Fiddaman 
226*43379a28SAndy Fiddaman 	if ((fd = open(filename, O_RDONLY)) == -1)
227*43379a28SAndy Fiddaman 		err(EXIT_FAILURE, "could not open '%s'", filename);
228*43379a28SAndy Fiddaman 
229*43379a28SAndy Fiddaman 	if (fstat(fd, &st) == -1)
230*43379a28SAndy Fiddaman 		err(EXIT_FAILURE, "failed to stat '%s'", filename);
231*43379a28SAndy Fiddaman 
232*43379a28SAndy Fiddaman 	p = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
233*43379a28SAndy Fiddaman 	if (p == MAP_FAILED)
234*43379a28SAndy Fiddaman 		err(EXIT_FAILURE, "failed to mmap 0x%lx bytes from '%s'",
235*43379a28SAndy Fiddaman 		    st.st_size, filename);
236*43379a28SAndy Fiddaman 
237*43379a28SAndy Fiddaman 	VERIFY0(close(fd));
238*43379a28SAndy Fiddaman 
239*43379a28SAndy Fiddaman 	*lenp = st.st_size;
240*43379a28SAndy Fiddaman 	return (p);
241*43379a28SAndy Fiddaman }
242*43379a28SAndy Fiddaman 
243*43379a28SAndy Fiddaman static void __PRINTFLIKE(2) __NORETURN
usage(int ec,const char * fmt,...)244*43379a28SAndy Fiddaman usage(int ec, const char *fmt, ...)
245*43379a28SAndy Fiddaman {
246*43379a28SAndy Fiddaman 	va_list ap;
247*43379a28SAndy Fiddaman 
248*43379a28SAndy Fiddaman 	if (fmt != NULL) {
249*43379a28SAndy Fiddaman 		va_start(ap, fmt);
250*43379a28SAndy Fiddaman 		(void) vfprintf(stderr, fmt, ap);
251*43379a28SAndy Fiddaman 		va_end(ap);
252*43379a28SAndy Fiddaman 		(void) fprintf(stderr, "\n");
253*43379a28SAndy Fiddaman 	}
254*43379a28SAndy Fiddaman 
255*43379a28SAndy Fiddaman 	(void) fprintf(stderr,
256*43379a28SAndy Fiddaman 	    "Usage:\n"
257*43379a28SAndy Fiddaman 	    "    -d <directory>  specify data directory\n"
258*43379a28SAndy Fiddaman 	    "                    (default: %s)\n"
259*43379a28SAndy Fiddaman 	    "    -g              generate baseline files\n"
260*43379a28SAndy Fiddaman 	    "    -h              show usage\n"
261*43379a28SAndy Fiddaman 	    "    -t <test>       run just the test named <test>\n"
262*43379a28SAndy Fiddaman 	    "    -v              send test output to stdout\n",
263*43379a28SAndy Fiddaman 	    DATADIR);
264*43379a28SAndy Fiddaman 	exit(ec);
265*43379a28SAndy Fiddaman }
266*43379a28SAndy Fiddaman 
267*43379a28SAndy Fiddaman int
main(int argc,char ** argv)268*43379a28SAndy Fiddaman main(int argc, char **argv)
269*43379a28SAndy Fiddaman {
270*43379a28SAndy Fiddaman 	uint8_t *data;
271*43379a28SAndy Fiddaman 	const char *datadir = DATADIR;
272*43379a28SAndy Fiddaman 	char buf[MAXPATHLEN + 1];
273*43379a28SAndy Fiddaman 	const char *test = NULL;
274*43379a28SAndy Fiddaman 	ilstr_t testout;
275*43379a28SAndy Fiddaman 	uint_t failures = 0;
276*43379a28SAndy Fiddaman 	size_t maplen;
277*43379a28SAndy Fiddaman 	int c;
278*43379a28SAndy Fiddaman 
279*43379a28SAndy Fiddaman 	enum {
280*43379a28SAndy Fiddaman 		MODE_TEST,
281*43379a28SAndy Fiddaman 		MODE_GENERATE,
282*43379a28SAndy Fiddaman 		MODE_DUMP
283*43379a28SAndy Fiddaman 	} testmode = MODE_TEST;
284*43379a28SAndy Fiddaman 
285*43379a28SAndy Fiddaman 	while ((c = getopt(argc, argv, ":d:ght:v")) != -1) {
286*43379a28SAndy Fiddaman 		switch (c) {
287*43379a28SAndy Fiddaman 		case 'd':
288*43379a28SAndy Fiddaman 			datadir = optarg;
289*43379a28SAndy Fiddaman 			break;
290*43379a28SAndy Fiddaman 		case 'g':
291*43379a28SAndy Fiddaman 			testmode = MODE_GENERATE;
292*43379a28SAndy Fiddaman 			break;
293*43379a28SAndy Fiddaman 		case 'h':
294*43379a28SAndy Fiddaman 			usage(0, NULL);
295*43379a28SAndy Fiddaman 		case 't':
296*43379a28SAndy Fiddaman 			test = optarg;
297*43379a28SAndy Fiddaman 			break;
298*43379a28SAndy Fiddaman 		case 'v':
299*43379a28SAndy Fiddaman 			testmode = MODE_DUMP;
300*43379a28SAndy Fiddaman 			break;
301*43379a28SAndy Fiddaman 		case ':':
302*43379a28SAndy Fiddaman 			usage(EXIT_FAILURE,
303*43379a28SAndy Fiddaman 			    "Option -%c requires an operand\n", optopt);
304*43379a28SAndy Fiddaman 		case '?':
305*43379a28SAndy Fiddaman 			usage(EXIT_FAILURE, "Unknown option: -%c", optopt);
306*43379a28SAndy Fiddaman 		}
307*43379a28SAndy Fiddaman 	}
308*43379a28SAndy Fiddaman 
309*43379a28SAndy Fiddaman 	if (snprintf(buf, sizeof (buf), "%s/_input", datadir) >= sizeof (buf))
310*43379a28SAndy Fiddaman 		errx(EXIT_FAILURE, "Overflow building data dir path");
311*43379a28SAndy Fiddaman 
312*43379a28SAndy Fiddaman 	data = mapfile(buf, &maplen);
313*43379a28SAndy Fiddaman 
314*43379a28SAndy Fiddaman 	ilstr_init(&testout, 0);
315*43379a28SAndy Fiddaman 
316*43379a28SAndy Fiddaman 	for (size_t i = 0; i < ARRAY_SIZE(tests); i++) {
317*43379a28SAndy Fiddaman 		if (test != NULL && strcmp(test, tests[i].name) != 0)
318*43379a28SAndy Fiddaman 			continue;
319*43379a28SAndy Fiddaman 
320*43379a28SAndy Fiddaman 		if (snprintf(buf, sizeof (buf), "%s/%s", datadir,
321*43379a28SAndy Fiddaman 		    tests[i].name) >= sizeof (buf)) {
322*43379a28SAndy Fiddaman 			errx(EXIT_FAILURE, "Overflow building output path");
323*43379a28SAndy Fiddaman 		}
324*43379a28SAndy Fiddaman 
325*43379a28SAndy Fiddaman 		run(&tests[i], data, maplen, &testout);
326*43379a28SAndy Fiddaman 
327*43379a28SAndy Fiddaman 		switch (testmode) {
328*43379a28SAndy Fiddaman 		case MODE_TEST: {
329*43379a28SAndy Fiddaman 			uint8_t *refdata;
330*43379a28SAndy Fiddaman 			size_t reflen;
331*43379a28SAndy Fiddaman 
332*43379a28SAndy Fiddaman 			refdata = mapfile(buf, &reflen);
333*43379a28SAndy Fiddaman 
334*43379a28SAndy Fiddaman 			if (ilstr_len(&testout) != reflen ||
335*43379a28SAndy Fiddaman 			    memcmp(ilstr_cstr(&testout), refdata,
336*43379a28SAndy Fiddaman 			    reflen) != 0) {
337*43379a28SAndy Fiddaman 				failures++;
338*43379a28SAndy Fiddaman 				(void) fprintf(stderr,
339*43379a28SAndy Fiddaman 				    "Hexdump '%s' output mismatch",
340*43379a28SAndy Fiddaman 				    tests[i].name);
341*43379a28SAndy Fiddaman 				(void) fprintf(stderr, "== Expected:\n%s\n",
342*43379a28SAndy Fiddaman 				    refdata);
343*43379a28SAndy Fiddaman 				(void) fprintf(stderr, "== Got:\n%s\n",
344*43379a28SAndy Fiddaman 				    ilstr_cstr(&testout));
345*43379a28SAndy Fiddaman 			}
346*43379a28SAndy Fiddaman 
347*43379a28SAndy Fiddaman 			VERIFY0(munmap(refdata, reflen));
348*43379a28SAndy Fiddaman 			break;
349*43379a28SAndy Fiddaman 		}
350*43379a28SAndy Fiddaman 		case MODE_GENERATE: {
351*43379a28SAndy Fiddaman 			FILE *fp;
352*43379a28SAndy Fiddaman 
353*43379a28SAndy Fiddaman 			fp = fopen(buf, "w");
354*43379a28SAndy Fiddaman 			if (fp == NULL)
355*43379a28SAndy Fiddaman 				err(EXIT_FAILURE, "Failed to create %s", buf);
356*43379a28SAndy Fiddaman 			(void) fprintf(fp, "%s", ilstr_cstr(&testout));
357*43379a28SAndy Fiddaman 			VERIFY0(fclose(fp));
358*43379a28SAndy Fiddaman 			break;
359*43379a28SAndy Fiddaman 		}
360*43379a28SAndy Fiddaman 		case MODE_DUMP:
361*43379a28SAndy Fiddaman 			(void) fprintf(stdout, "%s\n", ilstr_cstr(&testout));
362*43379a28SAndy Fiddaman 			break;
363*43379a28SAndy Fiddaman 		}
364*43379a28SAndy Fiddaman 		ilstr_reset(&testout);
365*43379a28SAndy Fiddaman 	}
366*43379a28SAndy Fiddaman 
367*43379a28SAndy Fiddaman 	ilstr_fini(&testout);
368*43379a28SAndy Fiddaman 
369*43379a28SAndy Fiddaman 	VERIFY0(munmap(data, maplen));
370*43379a28SAndy Fiddaman 
371*43379a28SAndy Fiddaman 	if (testmode == MODE_TEST && failures == 0)
372*43379a28SAndy Fiddaman 		(void) printf("All hexdump tests have passed.\n");
373*43379a28SAndy Fiddaman 
374*43379a28SAndy Fiddaman 	return (failures > 0 ? EXIT_FAILURE : 0);
375*43379a28SAndy Fiddaman }
376