xref: /freebsd/contrib/file/src/memtest.c (revision 43a5ec4eb41567cc92586503212743d89686d78f)
1*43a5ec4eSXin LI /*
2*43a5ec4eSXin LI  * Copyright (c) Christos Zoulas 2021.
3*43a5ec4eSXin LI  * All Rights Reserved.
4*43a5ec4eSXin LI  *
5*43a5ec4eSXin LI  * Redistribution and use in source and binary forms, with or without
6*43a5ec4eSXin LI  * modification, are permitted provided that the following conditions
7*43a5ec4eSXin LI  * are met:
8*43a5ec4eSXin LI  * 1. Redistributions of source code must retain the above copyright
9*43a5ec4eSXin LI  *    notice immediately at the beginning of the file, without modification,
10*43a5ec4eSXin LI  *    this list of conditions, and the following disclaimer.
11*43a5ec4eSXin LI  * 2. Redistributions in binary form must reproduce the above copyright
12*43a5ec4eSXin LI  *    notice, this list of conditions and the following disclaimer in the
13*43a5ec4eSXin LI  *    documentation and/or other materials provided with the distribution.
14*43a5ec4eSXin LI  *
15*43a5ec4eSXin LI  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16*43a5ec4eSXin LI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17*43a5ec4eSXin LI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18*43a5ec4eSXin LI  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
19*43a5ec4eSXin LI  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20*43a5ec4eSXin LI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21*43a5ec4eSXin LI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22*43a5ec4eSXin LI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23*43a5ec4eSXin LI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24*43a5ec4eSXin LI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25*43a5ec4eSXin LI  * SUCH DAMAGE.
26*43a5ec4eSXin LI  */
27*43a5ec4eSXin LI 
28*43a5ec4eSXin LI #include <sys/types.h>
29*43a5ec4eSXin LI #include <sys/stat.h>
30*43a5ec4eSXin LI #include <sys/mman.h>
31*43a5ec4eSXin LI #include <stdio.h>
32*43a5ec4eSXin LI #include <stdbool.h>
33*43a5ec4eSXin LI #include <string.h>
34*43a5ec4eSXin LI #include <stdlib.h>
35*43a5ec4eSXin LI #include <err.h>
36*43a5ec4eSXin LI #include <fcntl.h>
37*43a5ec4eSXin LI #include <unistd.h>
38*43a5ec4eSXin LI #include <dlfcn.h>
39*43a5ec4eSXin LI #include <magic.h>
40*43a5ec4eSXin LI 
41*43a5ec4eSXin LI void *
42*43a5ec4eSXin LI malloc(size_t len)
43*43a5ec4eSXin LI {
44*43a5ec4eSXin LI 	char buf[512];
45*43a5ec4eSXin LI 	void *(*orig)(size_t) = dlsym(RTLD_NEXT, "malloc");
46*43a5ec4eSXin LI 	void *p = (*orig)(len);
47*43a5ec4eSXin LI 	int l = snprintf(buf, sizeof(buf), "malloc %zu %p\n", len, p);
48*43a5ec4eSXin LI 	write(2, buf, l);
49*43a5ec4eSXin LI 	return p;
50*43a5ec4eSXin LI }
51*43a5ec4eSXin LI 
52*43a5ec4eSXin LI void
53*43a5ec4eSXin LI free(void *p)
54*43a5ec4eSXin LI {
55*43a5ec4eSXin LI 	char buf[512];
56*43a5ec4eSXin LI 	void (*orig)(void *) = dlsym(RTLD_NEXT, "free");
57*43a5ec4eSXin LI 	(*orig)(p);
58*43a5ec4eSXin LI 	int l = snprintf(buf, sizeof(buf), "free %p\n", p);
59*43a5ec4eSXin LI 	write(2, buf, l);
60*43a5ec4eSXin LI }
61*43a5ec4eSXin LI 
62*43a5ec4eSXin LI void *
63*43a5ec4eSXin LI calloc(size_t len, size_t nitems)
64*43a5ec4eSXin LI {
65*43a5ec4eSXin LI 	char buf[512];
66*43a5ec4eSXin LI 	void *(*orig)(size_t, size_t) = dlsym(RTLD_NEXT, "calloc");
67*43a5ec4eSXin LI 	void *p = (*orig)(len, nitems);
68*43a5ec4eSXin LI 	size_t tot = len * nitems;
69*43a5ec4eSXin LI 	int l = snprintf(buf, sizeof(buf), "calloc %zu %p\n", tot, p);
70*43a5ec4eSXin LI 	write(2, buf, l);
71*43a5ec4eSXin LI 	return p;
72*43a5ec4eSXin LI }
73*43a5ec4eSXin LI void *
74*43a5ec4eSXin LI realloc(void *q, size_t len)
75*43a5ec4eSXin LI {
76*43a5ec4eSXin LI 	char buf[512];
77*43a5ec4eSXin LI 	void *(*orig)(void *, size_t) = dlsym(RTLD_NEXT, "realloc");
78*43a5ec4eSXin LI 	void *p = (*orig)(q, len);
79*43a5ec4eSXin LI 	int l = snprintf(buf, sizeof(buf), "realloc %zu %p\n", len, p);
80*43a5ec4eSXin LI 	write(2, buf, l);
81*43a5ec4eSXin LI 	return p;
82*43a5ec4eSXin LI }
83*43a5ec4eSXin LI 
84*43a5ec4eSXin LI static void
85*43a5ec4eSXin LI usage(void)
86*43a5ec4eSXin LI {
87*43a5ec4eSXin LI 	fprintf(stderr, "Usage: test [-b] <filename>\n");
88*43a5ec4eSXin LI 	exit(EXIT_FAILURE);
89*43a5ec4eSXin LI }
90*43a5ec4eSXin LI 
91*43a5ec4eSXin LI int
92*43a5ec4eSXin LI main(int argc, char *argv[])
93*43a5ec4eSXin LI {
94*43a5ec4eSXin LI 	bool buf = false;
95*43a5ec4eSXin LI 	int c;
96*43a5ec4eSXin LI 
97*43a5ec4eSXin LI 	while ((c = getopt(argc, argv, "b")) != -1)
98*43a5ec4eSXin LI 		switch (c) {
99*43a5ec4eSXin LI 		case 'b':
100*43a5ec4eSXin LI 			buf = true;
101*43a5ec4eSXin LI 			break;
102*43a5ec4eSXin LI 		default:
103*43a5ec4eSXin LI 			usage();
104*43a5ec4eSXin LI 		}
105*43a5ec4eSXin LI 
106*43a5ec4eSXin LI 	argc -= optind;
107*43a5ec4eSXin LI 	argv += optind;
108*43a5ec4eSXin LI 
109*43a5ec4eSXin LI 	if (argc == 0)
110*43a5ec4eSXin LI 		usage();
111*43a5ec4eSXin LI 
112*43a5ec4eSXin LI 	magic_t m = magic_open(0);
113*43a5ec4eSXin LI 	if (m == NULL)
114*43a5ec4eSXin LI 		err(EXIT_FAILURE, "magic_open");
115*43a5ec4eSXin LI 
116*43a5ec4eSXin LI 	magic_load(m, NULL);
117*43a5ec4eSXin LI 
118*43a5ec4eSXin LI 	const char *r;
119*43a5ec4eSXin LI 	if (buf) {
120*43a5ec4eSXin LI 		int fd = open(argv[0], O_RDONLY);
121*43a5ec4eSXin LI 		if (fd == -1)
122*43a5ec4eSXin LI 			err(EXIT_FAILURE, "Cannot open `%s'", argv[0]);
123*43a5ec4eSXin LI 
124*43a5ec4eSXin LI 		struct stat st;
125*43a5ec4eSXin LI 		if (fstat(fd, &st) == -1)
126*43a5ec4eSXin LI 			err(EXIT_FAILURE, "Cannot stat `%s'", argv[0]);
127*43a5ec4eSXin LI 		size_t l = (size_t)st.st_size;
128*43a5ec4eSXin LI 		void *p = mmap(NULL, l, PROT_READ, MAP_FILE | MAP_PRIVATE, fd,
129*43a5ec4eSXin LI 		    (off_t)0);
130*43a5ec4eSXin LI 		if (p == MAP_FAILED)
131*43a5ec4eSXin LI 			err(EXIT_FAILURE, "Cannot map `%s'", argv[0]);
132*43a5ec4eSXin LI 		close(fd);
133*43a5ec4eSXin LI 		r = magic_buffer(m, p, l);
134*43a5ec4eSXin LI 		munmap(p, l);
135*43a5ec4eSXin LI 	} else {
136*43a5ec4eSXin LI 		r = magic_file(m, argv[0]);
137*43a5ec4eSXin LI 	}
138*43a5ec4eSXin LI 	magic_close(m);
139*43a5ec4eSXin LI 
140*43a5ec4eSXin LI 	printf("%s\n", r ? r : "(null)");
141*43a5ec4eSXin LI 
142*43a5ec4eSXin LI 	return 0;
143*43a5ec4eSXin LI }
144