xref: /freebsd/contrib/file/src/memtest.c (revision 38a52bd3)
1 /*
2  * Copyright (c) Christos Zoulas 2021.
3  * All Rights Reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice immediately at the beginning of the file, without modification,
10  *    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 FOR
19  * 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 #ifndef lint
29 FILE_RCSID("@(#)$File: memtest.c,v 1.3 2022/09/13 18:46:07 christos Exp $")
30 #endif
31 
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/mman.h>
35 #include <stdio.h>
36 #include <stdbool.h>
37 #include <string.h>
38 #include <stdlib.h>
39 #include <err.h>
40 #include <fcntl.h>
41 #include <unistd.h>
42 #include <dlfcn.h>
43 #include <magic.h>
44 
45 void *
46 malloc(size_t len)
47 {
48 	char buf[512];
49 	void *(*orig)(size_t) = dlsym(RTLD_NEXT, "malloc");
50 	void *p = (*orig)(len);
51 	int l = snprintf(buf, sizeof(buf), "malloc %zu %p\n", len, p);
52 	write(2, buf, l);
53 	return p;
54 }
55 
56 void
57 free(void *p)
58 {
59 	char buf[512];
60 	void (*orig)(void *) = dlsym(RTLD_NEXT, "free");
61 	(*orig)(p);
62 	int l = snprintf(buf, sizeof(buf), "free %p\n", p);
63 	write(2, buf, l);
64 }
65 
66 void *
67 calloc(size_t len, size_t nitems)
68 {
69 	char buf[512];
70 	void *(*orig)(size_t, size_t) = dlsym(RTLD_NEXT, "calloc");
71 	void *p = (*orig)(len, nitems);
72 	size_t tot = len * nitems;
73 	int l = snprintf(buf, sizeof(buf), "calloc %zu %p\n", tot, p);
74 	write(2, buf, l);
75 	return p;
76 }
77 void *
78 realloc(void *q, size_t len)
79 {
80 	char buf[512];
81 	void *(*orig)(void *, size_t) = dlsym(RTLD_NEXT, "realloc");
82 	void *p = (*orig)(q, len);
83 	int l = snprintf(buf, sizeof(buf), "realloc %zu %p\n", len, p);
84 	write(2, buf, l);
85 	return p;
86 }
87 
88 static void
89 usage(void)
90 {
91 	fprintf(stderr, "Usage: test [-b] <filename>\n");
92 	exit(EXIT_FAILURE);
93 }
94 
95 int
96 main(int argc, char *argv[])
97 {
98 	bool buf = false;
99 	int c;
100 
101 	while ((c = getopt(argc, argv, "b")) != -1)
102 		switch (c) {
103 		case 'b':
104 			buf = true;
105 			break;
106 		default:
107 			usage();
108 		}
109 
110 	argc -= optind;
111 	argv += optind;
112 
113 	if (argc == 0)
114 		usage();
115 
116 	magic_t m = magic_open(0);
117 	if (m == NULL)
118 		err(EXIT_FAILURE, "magic_open");
119 
120 	magic_load(m, NULL);
121 
122 	const char *r;
123 	if (buf) {
124 		int fd = open(argv[0], O_RDONLY);
125 		if (fd == -1)
126 			err(EXIT_FAILURE, "Cannot open `%s'", argv[0]);
127 
128 		struct stat st;
129 		if (fstat(fd, &st) == -1)
130 			err(EXIT_FAILURE, "Cannot stat `%s'", argv[0]);
131 		size_t l = (size_t)st.st_size;
132 		void *p = mmap(NULL, l, PROT_READ, MAP_FILE | MAP_PRIVATE, fd,
133 		    (off_t)0);
134 		if (p == MAP_FAILED)
135 			err(EXIT_FAILURE, "Cannot map `%s'", argv[0]);
136 		close(fd);
137 		r = magic_buffer(m, p, l);
138 		munmap(p, l);
139 	} else {
140 		r = magic_file(m, argv[0]);
141 	}
142 	magic_close(m);
143 
144 	printf("%s\n", r ? r : "(null)");
145 
146 	return 0;
147 }
148