xref: /aosp_15_r20/external/kmod/testsuite/path.c (revision cc4ad7da8cefe208cb129ac2aa9a357c7c72deb2)
1*cc4ad7daSAndroid Build Coastguard Worker /*
2*cc4ad7daSAndroid Build Coastguard Worker  * Copyright (C) 2012-2013  ProFUSION embedded systems
3*cc4ad7daSAndroid Build Coastguard Worker  *
4*cc4ad7daSAndroid Build Coastguard Worker  * This program is free software; you can redistribute it and/or
5*cc4ad7daSAndroid Build Coastguard Worker  * modify it under the terms of the GNU Lesser General Public
6*cc4ad7daSAndroid Build Coastguard Worker  * License as published by the Free Software Foundation; either
7*cc4ad7daSAndroid Build Coastguard Worker  * version 2.1 of the License, or (at your option) any later version.
8*cc4ad7daSAndroid Build Coastguard Worker  *
9*cc4ad7daSAndroid Build Coastguard Worker  * This program is distributed in the hope that it will be useful,
10*cc4ad7daSAndroid Build Coastguard Worker  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*cc4ad7daSAndroid Build Coastguard Worker  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12*cc4ad7daSAndroid Build Coastguard Worker  * Lesser General Public License for more details.
13*cc4ad7daSAndroid Build Coastguard Worker  *
14*cc4ad7daSAndroid Build Coastguard Worker  * You should have received a copy of the GNU Lesser General Public
15*cc4ad7daSAndroid Build Coastguard Worker  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16*cc4ad7daSAndroid Build Coastguard Worker  */
17*cc4ad7daSAndroid Build Coastguard Worker 
18*cc4ad7daSAndroid Build Coastguard Worker /* We unset _FILE_OFFSET_BITS here so we can override both stat and stat64 on
19*cc4ad7daSAndroid Build Coastguard Worker  * 32-bit architectures and forward each to the right libc function */
20*cc4ad7daSAndroid Build Coastguard Worker #undef _FILE_OFFSET_BITS
21*cc4ad7daSAndroid Build Coastguard Worker 
22*cc4ad7daSAndroid Build Coastguard Worker #include <assert.h>
23*cc4ad7daSAndroid Build Coastguard Worker #include <dirent.h>
24*cc4ad7daSAndroid Build Coastguard Worker #include <dlfcn.h>
25*cc4ad7daSAndroid Build Coastguard Worker #include <errno.h>
26*cc4ad7daSAndroid Build Coastguard Worker #include <fcntl.h>
27*cc4ad7daSAndroid Build Coastguard Worker #include <limits.h>
28*cc4ad7daSAndroid Build Coastguard Worker #include <stdarg.h>
29*cc4ad7daSAndroid Build Coastguard Worker #include <stdio.h>
30*cc4ad7daSAndroid Build Coastguard Worker #include <stdlib.h>
31*cc4ad7daSAndroid Build Coastguard Worker #include <string.h>
32*cc4ad7daSAndroid Build Coastguard Worker #include <unistd.h>
33*cc4ad7daSAndroid Build Coastguard Worker #include <sys/stat.h>
34*cc4ad7daSAndroid Build Coastguard Worker #include <sys/types.h>
35*cc4ad7daSAndroid Build Coastguard Worker 
36*cc4ad7daSAndroid Build Coastguard Worker #include <shared/util.h>
37*cc4ad7daSAndroid Build Coastguard Worker 
38*cc4ad7daSAndroid Build Coastguard Worker #include "testsuite.h"
39*cc4ad7daSAndroid Build Coastguard Worker 
40*cc4ad7daSAndroid Build Coastguard Worker static void *nextlib;
41*cc4ad7daSAndroid Build Coastguard Worker static const char *rootpath;
42*cc4ad7daSAndroid Build Coastguard Worker static size_t rootpathlen;
43*cc4ad7daSAndroid Build Coastguard Worker 
need_trap(const char * path)44*cc4ad7daSAndroid Build Coastguard Worker static inline bool need_trap(const char *path)
45*cc4ad7daSAndroid Build Coastguard Worker {
46*cc4ad7daSAndroid Build Coastguard Worker 	return path != NULL && path[0] == '/'
47*cc4ad7daSAndroid Build Coastguard Worker 		&& !strstartswith(path, ABS_TOP_BUILDDIR);
48*cc4ad7daSAndroid Build Coastguard Worker }
49*cc4ad7daSAndroid Build Coastguard Worker 
trap_path(const char * path,char buf[PATH_MAX * 2])50*cc4ad7daSAndroid Build Coastguard Worker static const char *trap_path(const char *path, char buf[PATH_MAX * 2])
51*cc4ad7daSAndroid Build Coastguard Worker {
52*cc4ad7daSAndroid Build Coastguard Worker 	size_t len;
53*cc4ad7daSAndroid Build Coastguard Worker 
54*cc4ad7daSAndroid Build Coastguard Worker 	if (!need_trap(path))
55*cc4ad7daSAndroid Build Coastguard Worker 		return path;
56*cc4ad7daSAndroid Build Coastguard Worker 
57*cc4ad7daSAndroid Build Coastguard Worker 	len = strlen(path);
58*cc4ad7daSAndroid Build Coastguard Worker 
59*cc4ad7daSAndroid Build Coastguard Worker 	if (len + rootpathlen > PATH_MAX * 2) {
60*cc4ad7daSAndroid Build Coastguard Worker 		errno = ENAMETOOLONG;
61*cc4ad7daSAndroid Build Coastguard Worker 		return NULL;
62*cc4ad7daSAndroid Build Coastguard Worker 	}
63*cc4ad7daSAndroid Build Coastguard Worker 
64*cc4ad7daSAndroid Build Coastguard Worker 	memcpy(buf, rootpath, rootpathlen);
65*cc4ad7daSAndroid Build Coastguard Worker 	strcpy(buf + rootpathlen, path);
66*cc4ad7daSAndroid Build Coastguard Worker 	return buf;
67*cc4ad7daSAndroid Build Coastguard Worker }
68*cc4ad7daSAndroid Build Coastguard Worker 
get_rootpath(const char * f)69*cc4ad7daSAndroid Build Coastguard Worker static bool get_rootpath(const char *f)
70*cc4ad7daSAndroid Build Coastguard Worker {
71*cc4ad7daSAndroid Build Coastguard Worker 	if (rootpath != NULL)
72*cc4ad7daSAndroid Build Coastguard Worker 		return true;
73*cc4ad7daSAndroid Build Coastguard Worker 
74*cc4ad7daSAndroid Build Coastguard Worker 	rootpath = getenv(S_TC_ROOTFS);
75*cc4ad7daSAndroid Build Coastguard Worker 	if (rootpath == NULL) {
76*cc4ad7daSAndroid Build Coastguard Worker 		ERR("TRAP %s(): missing export %s?\n", f, S_TC_ROOTFS);
77*cc4ad7daSAndroid Build Coastguard Worker 		errno = ENOENT;
78*cc4ad7daSAndroid Build Coastguard Worker 		return false;
79*cc4ad7daSAndroid Build Coastguard Worker 	}
80*cc4ad7daSAndroid Build Coastguard Worker 
81*cc4ad7daSAndroid Build Coastguard Worker 	rootpathlen = strlen(rootpath);
82*cc4ad7daSAndroid Build Coastguard Worker 
83*cc4ad7daSAndroid Build Coastguard Worker 	return true;
84*cc4ad7daSAndroid Build Coastguard Worker }
85*cc4ad7daSAndroid Build Coastguard Worker 
get_libc_func(const char * f)86*cc4ad7daSAndroid Build Coastguard Worker static void *get_libc_func(const char *f)
87*cc4ad7daSAndroid Build Coastguard Worker {
88*cc4ad7daSAndroid Build Coastguard Worker 	void *fp;
89*cc4ad7daSAndroid Build Coastguard Worker 
90*cc4ad7daSAndroid Build Coastguard Worker 	if (nextlib == NULL) {
91*cc4ad7daSAndroid Build Coastguard Worker #ifdef RTLD_NEXT
92*cc4ad7daSAndroid Build Coastguard Worker 		nextlib = RTLD_NEXT;
93*cc4ad7daSAndroid Build Coastguard Worker #else
94*cc4ad7daSAndroid Build Coastguard Worker 		nextlib = dlopen("libc.so.6", RTLD_LAZY);
95*cc4ad7daSAndroid Build Coastguard Worker #endif
96*cc4ad7daSAndroid Build Coastguard Worker 	}
97*cc4ad7daSAndroid Build Coastguard Worker 
98*cc4ad7daSAndroid Build Coastguard Worker 	fp = dlsym(nextlib, f);
99*cc4ad7daSAndroid Build Coastguard Worker 	assert(fp);
100*cc4ad7daSAndroid Build Coastguard Worker 
101*cc4ad7daSAndroid Build Coastguard Worker 	return fp;
102*cc4ad7daSAndroid Build Coastguard Worker }
103*cc4ad7daSAndroid Build Coastguard Worker 
104*cc4ad7daSAndroid Build Coastguard Worker /* wrapper template for a function with one "const char* path" argument */
105*cc4ad7daSAndroid Build Coastguard Worker #define WRAP_1ARG(rettype, failret, name) \
106*cc4ad7daSAndroid Build Coastguard Worker TS_EXPORT rettype name(const char *path) \
107*cc4ad7daSAndroid Build Coastguard Worker { \
108*cc4ad7daSAndroid Build Coastguard Worker 	const char *p;				\
109*cc4ad7daSAndroid Build Coastguard Worker 	char buf[PATH_MAX * 2];                 \
110*cc4ad7daSAndroid Build Coastguard Worker 	static rettype (*_fn)(const char*);	\
111*cc4ad7daSAndroid Build Coastguard Worker 						\
112*cc4ad7daSAndroid Build Coastguard Worker 	if (!get_rootpath(__func__))		\
113*cc4ad7daSAndroid Build Coastguard Worker 		return failret;			\
114*cc4ad7daSAndroid Build Coastguard Worker 	_fn = get_libc_func(#name);		\
115*cc4ad7daSAndroid Build Coastguard Worker 	p = trap_path(path, buf);		\
116*cc4ad7daSAndroid Build Coastguard Worker 	if (p == NULL)				\
117*cc4ad7daSAndroid Build Coastguard Worker 		return failret;			\
118*cc4ad7daSAndroid Build Coastguard Worker 	return (*_fn)(p);			\
119*cc4ad7daSAndroid Build Coastguard Worker }
120*cc4ad7daSAndroid Build Coastguard Worker 
121*cc4ad7daSAndroid Build Coastguard Worker /* wrapper template for a function with "const char* path" and another argument */
122*cc4ad7daSAndroid Build Coastguard Worker #define WRAP_2ARGS(rettype, failret, name, arg2t)	\
123*cc4ad7daSAndroid Build Coastguard Worker TS_EXPORT rettype name(const char *path, arg2t arg2)	\
124*cc4ad7daSAndroid Build Coastguard Worker { \
125*cc4ad7daSAndroid Build Coastguard Worker 	const char *p;					\
126*cc4ad7daSAndroid Build Coastguard Worker 	char buf[PATH_MAX * 2];				\
127*cc4ad7daSAndroid Build Coastguard Worker 	static rettype (*_fn)(const char*, arg2t arg2);	\
128*cc4ad7daSAndroid Build Coastguard Worker 							\
129*cc4ad7daSAndroid Build Coastguard Worker 	if (!get_rootpath(__func__))			\
130*cc4ad7daSAndroid Build Coastguard Worker 		return failret;				\
131*cc4ad7daSAndroid Build Coastguard Worker 	_fn = get_libc_func(#name);			\
132*cc4ad7daSAndroid Build Coastguard Worker 	p = trap_path(path, buf);			\
133*cc4ad7daSAndroid Build Coastguard Worker 	if (p == NULL)					\
134*cc4ad7daSAndroid Build Coastguard Worker 		return failret;				\
135*cc4ad7daSAndroid Build Coastguard Worker 	return (*_fn)(p, arg2);				\
136*cc4ad7daSAndroid Build Coastguard Worker }
137*cc4ad7daSAndroid Build Coastguard Worker 
138*cc4ad7daSAndroid Build Coastguard Worker /* wrapper template for open family */
139*cc4ad7daSAndroid Build Coastguard Worker #define WRAP_OPEN(suffix)					\
140*cc4ad7daSAndroid Build Coastguard Worker TS_EXPORT int open ## suffix (const char *path, int flags, ...)	\
141*cc4ad7daSAndroid Build Coastguard Worker { \
142*cc4ad7daSAndroid Build Coastguard Worker 	const char *p;						\
143*cc4ad7daSAndroid Build Coastguard Worker 	char buf[PATH_MAX * 2];					\
144*cc4ad7daSAndroid Build Coastguard Worker 	static int (*_fn)(const char *path, int flags, ...);	\
145*cc4ad7daSAndroid Build Coastguard Worker 								\
146*cc4ad7daSAndroid Build Coastguard Worker 	if (!get_rootpath(__func__))				\
147*cc4ad7daSAndroid Build Coastguard Worker 		return -1;					\
148*cc4ad7daSAndroid Build Coastguard Worker 	_fn = get_libc_func("open" #suffix);			\
149*cc4ad7daSAndroid Build Coastguard Worker 	p = trap_path(path, buf);				\
150*cc4ad7daSAndroid Build Coastguard Worker 	if (p == NULL)						\
151*cc4ad7daSAndroid Build Coastguard Worker 		return -1;					\
152*cc4ad7daSAndroid Build Coastguard Worker 								\
153*cc4ad7daSAndroid Build Coastguard Worker 	if (flags & O_CREAT) {					\
154*cc4ad7daSAndroid Build Coastguard Worker 		mode_t mode;					\
155*cc4ad7daSAndroid Build Coastguard Worker 		va_list ap;					\
156*cc4ad7daSAndroid Build Coastguard Worker 								\
157*cc4ad7daSAndroid Build Coastguard Worker 		va_start(ap, flags);				\
158*cc4ad7daSAndroid Build Coastguard Worker 		mode = va_arg(ap, mode_t);			\
159*cc4ad7daSAndroid Build Coastguard Worker 		va_end(ap);					\
160*cc4ad7daSAndroid Build Coastguard Worker 		return _fn(p, flags, mode);			\
161*cc4ad7daSAndroid Build Coastguard Worker 	}							\
162*cc4ad7daSAndroid Build Coastguard Worker 								\
163*cc4ad7daSAndroid Build Coastguard Worker 	return _fn(p, flags);					\
164*cc4ad7daSAndroid Build Coastguard Worker }
165*cc4ad7daSAndroid Build Coastguard Worker 
166*cc4ad7daSAndroid Build Coastguard Worker /*
167*cc4ad7daSAndroid Build Coastguard Worker  * wrapper template for __xstat family
168*cc4ad7daSAndroid Build Coastguard Worker  * This family got deprecated/dropped in glibc 2.32.9000, but we still need
169*cc4ad7daSAndroid Build Coastguard Worker  * to keep it for a while for programs that were built against previous versions
170*cc4ad7daSAndroid Build Coastguard Worker  */
171*cc4ad7daSAndroid Build Coastguard Worker #define WRAP_VERSTAT(prefix, suffix)			    \
172*cc4ad7daSAndroid Build Coastguard Worker TS_EXPORT int prefix ## stat ## suffix (int ver,	    \
173*cc4ad7daSAndroid Build Coastguard Worker 			      const char *path,		    \
174*cc4ad7daSAndroid Build Coastguard Worker 	                      struct stat ## suffix *st);   \
175*cc4ad7daSAndroid Build Coastguard Worker TS_EXPORT int prefix ## stat ## suffix (int ver,	    \
176*cc4ad7daSAndroid Build Coastguard Worker 			      const char *path,		    \
177*cc4ad7daSAndroid Build Coastguard Worker 	                      struct stat ## suffix *st)    \
178*cc4ad7daSAndroid Build Coastguard Worker { \
179*cc4ad7daSAndroid Build Coastguard Worker 	const char *p;					    \
180*cc4ad7daSAndroid Build Coastguard Worker 	char buf[PATH_MAX * 2];				    \
181*cc4ad7daSAndroid Build Coastguard Worker 	static int (*_fn)(int ver, const char *path,	    \
182*cc4ad7daSAndroid Build Coastguard Worker 		          struct stat ## suffix *);	    \
183*cc4ad7daSAndroid Build Coastguard Worker 	_fn = get_libc_func(#prefix "stat" #suffix);	    \
184*cc4ad7daSAndroid Build Coastguard Worker 							    \
185*cc4ad7daSAndroid Build Coastguard Worker 	if (!get_rootpath(__func__))			    \
186*cc4ad7daSAndroid Build Coastguard Worker 		return -1;				    \
187*cc4ad7daSAndroid Build Coastguard Worker 	p = trap_path(path, buf);			    \
188*cc4ad7daSAndroid Build Coastguard Worker 	if (p == NULL)					    \
189*cc4ad7daSAndroid Build Coastguard Worker 		return -1;				    \
190*cc4ad7daSAndroid Build Coastguard Worker 							    \
191*cc4ad7daSAndroid Build Coastguard Worker 	return _fn(ver, p, st);				    \
192*cc4ad7daSAndroid Build Coastguard Worker }
193*cc4ad7daSAndroid Build Coastguard Worker 
194*cc4ad7daSAndroid Build Coastguard Worker WRAP_1ARG(DIR*, NULL, opendir);
195*cc4ad7daSAndroid Build Coastguard Worker WRAP_1ARG(int, -1, chdir);
196*cc4ad7daSAndroid Build Coastguard Worker 
197*cc4ad7daSAndroid Build Coastguard Worker WRAP_2ARGS(FILE*, NULL, fopen, const char*);
198*cc4ad7daSAndroid Build Coastguard Worker WRAP_2ARGS(FILE*, NULL, fopen64, const char*);
199*cc4ad7daSAndroid Build Coastguard Worker WRAP_2ARGS(int, -1, mkdir, mode_t);
200*cc4ad7daSAndroid Build Coastguard Worker WRAP_2ARGS(int, -1, access, int);
201*cc4ad7daSAndroid Build Coastguard Worker WRAP_2ARGS(int, -1, stat, struct stat*);
202*cc4ad7daSAndroid Build Coastguard Worker WRAP_2ARGS(int, -1, lstat, struct stat*);
203*cc4ad7daSAndroid Build Coastguard Worker WRAP_2ARGS(int, -1, stat64, struct stat64*);
204*cc4ad7daSAndroid Build Coastguard Worker WRAP_2ARGS(int, -1, lstat64, struct stat64*);
205*cc4ad7daSAndroid Build Coastguard Worker WRAP_OPEN(64);
206*cc4ad7daSAndroid Build Coastguard Worker 
207*cc4ad7daSAndroid Build Coastguard Worker WRAP_OPEN();
208*cc4ad7daSAndroid Build Coastguard Worker 
209*cc4ad7daSAndroid Build Coastguard Worker #ifdef HAVE___XSTAT
210*cc4ad7daSAndroid Build Coastguard Worker WRAP_VERSTAT(__x,);
211*cc4ad7daSAndroid Build Coastguard Worker WRAP_VERSTAT(__lx,);
212*cc4ad7daSAndroid Build Coastguard Worker WRAP_VERSTAT(__x,64);
213*cc4ad7daSAndroid Build Coastguard Worker WRAP_VERSTAT(__lx,64);
214*cc4ad7daSAndroid Build Coastguard Worker #endif
215