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