]> git.ipfire.org Git - thirdparty/kmod.git/blame - testsuite/path.c
testsuite: check if rootfs dir is dirty before running
[thirdparty/kmod.git] / testsuite / path.c
CommitLineData
e701e381
LDM
1/*
2 * Copyright (C) 2012 ProFUSION embedded systems
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
6afc9cd6
LDM
18#include <assert.h>
19#include <errno.h>
4e36cb18 20#include <dirent.h>
7fa8c2d2 21#include <fcntl.h>
6afc9cd6
LDM
22#include <dlfcn.h>
23#include <limits.h>
24#include <stdlib.h>
7fa8c2d2 25#include <stdarg.h>
6afc9cd6
LDM
26#include <string.h>
27#include <stdio.h>
7fa8c2d2
LDM
28#include <sys/types.h>
29#include <sys/stat.h>
1426a613 30#include <unistd.h>
6afc9cd6
LDM
31
32#include "testsuite.h"
33
34static void *nextlib;
35static const char *rootpath;
36static size_t rootpathlen;
37
38static inline bool need_trap(const char *path)
39{
40 return path != NULL && path[0] == '/';
41}
42
43static const char *trap_path(const char *path, char buf[PATH_MAX * 2])
44{
45 size_t len;
46
47 if (!need_trap(path))
48 return path;
49
50 len = strlen(path);
51
52 if (len + rootpathlen > PATH_MAX * 2) {
53 errno = ENAMETOOLONG;
54 return NULL;
55 }
56
57 memcpy(buf, rootpath, rootpathlen);
58 strcpy(buf + rootpathlen, path);
59 return buf;
60}
61
62static bool get_rootpath(const char *f)
63{
64 if (rootpath != NULL)
65 return true;
66
67 rootpath = getenv(S_TC_ROOTFS);
68 if (rootpath == NULL) {
69 ERR("TRAP %s(): missing export %s?\n", f, S_TC_ROOTFS);
70 errno = ENOENT;
71 return false;
72 }
73
74 rootpathlen = strlen(rootpath);
75
76 return true;
77}
78
79static void *get_libc_func(const char *f)
80{
81 void *fp;
82
83 if (nextlib == NULL) {
84#ifdef RTLD_NEXT
85 nextlib = RTLD_NEXT;
86#else
87 nextlib = dlopen("libc.so.6", RTLD_LAZY);
88#endif
89 }
90
91 fp = dlsym(nextlib, f);
92 assert(fp);
93
94 return fp;
95}
96
97TS_EXPORT FILE *fopen(const char *path, const char *mode)
98{
99 const char *p;
100 char buf[PATH_MAX * 2];
f6301b65 101 static FILE* (*_fopen)(const char *path, const char *mode);
6afc9cd6
LDM
102
103 if (!get_rootpath(__func__))
104 return NULL;
105
106 _fopen = get_libc_func("fopen");
107
108 p = trap_path(path, buf);
109 if (p == NULL)
110 return NULL;
111
f6301b65 112 return (*_fopen)(p, mode);
6afc9cd6 113}
7fa8c2d2
LDM
114
115TS_EXPORT int open(const char *path, int flags, ...)
116{
117 const char *p;
118 char buf[PATH_MAX * 2];
119 static int (*_open)(const char *path, int flags, ...);
120
121 if (!get_rootpath(__func__))
122 return -1;
123
124 _open = get_libc_func("open");
125 p = trap_path(path, buf);
126 if (p == NULL)
127 return -1;
128
129 if (flags & O_CREAT) {
130 mode_t mode;
131 va_list ap;
132
133 va_start(ap, flags);
134 mode = va_arg(ap, mode_t);
135 va_end(ap);
136 _open(p, flags, mode);
137 }
138
139 return _open(p, flags);
140}
1426a613
LDM
141
142TS_EXPORT int stat(const char *path, struct stat *st)
143{
144 const char *p;
145 char buf[PATH_MAX * 2];
146 static int (*_stat)(const char *path, struct stat *buf);
147
148 if (!get_rootpath(__func__))
149 return -1;
150
151 _stat = get_libc_func("stat");
152
153 p = trap_path(path, buf);
154 if (p == NULL)
155 return -1;
156
157 return _stat(p, st);
158}
159
d005aeb7 160#ifdef HAVE___XSTAT
1426a613
LDM
161TS_EXPORT int __xstat(int ver, const char *path, struct stat *st)
162{
163 const char *p;
164 char buf[PATH_MAX * 2];
165 static int (*_xstat)(int __ver, const char *__filename,
166 struct stat *__stat_buf);
167
168 if (!get_rootpath(__func__))
169 return -1;
170
171 _xstat = get_libc_func("__xstat");
172
173 p = trap_path(path, buf);
174 if (p == NULL)
175 return -1;
176
177 return _xstat(ver, p, st);
178}
d005aeb7 179#endif
1426a613
LDM
180
181TS_EXPORT int access(const char *path, int mode)
182{
183 const char *p;
184 char buf[PATH_MAX * 2];
185 static int (*_access)(const char *path, int mode);
186
187 if (!get_rootpath(__func__))
188 return -1;
189
190 _access = get_libc_func("access");
191
192 p = trap_path(path, buf);
193 if (p == NULL)
194 return -1;
195
196 return _access(p, mode);
197}
4e36cb18
LDM
198
199TS_EXPORT DIR *opendir(const char *path)
200{
201 const char *p;
202 char buf[PATH_MAX * 2];
f6301b65 203 static DIR* (*_opendir)(const char *path);
4e36cb18
LDM
204
205 if (!get_rootpath(__func__))
206 return NULL;
207
208 _opendir = get_libc_func("opendir");
209
210 p = trap_path(path, buf);
211 if (p == NULL)
212 return NULL;
213
f6301b65 214 return (*_opendir)(p);
4e36cb18 215}