]> git.ipfire.org Git - thirdparty/kmod.git/blame - testsuite/path.c
Remove FSF mailing address
[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
6afc9cd6 18#include <assert.h>
4e36cb18 19#include <dirent.h>
6afc9cd6 20#include <dlfcn.h>
c2e4286b
LDM
21#include <errno.h>
22#include <fcntl.h>
6afc9cd6 23#include <limits.h>
7fa8c2d2 24#include <stdarg.h>
6afc9cd6 25#include <stdio.h>
c2e4286b
LDM
26#include <stdlib.h>
27#include <string.h>
1426a613 28#include <unistd.h>
c2e4286b
LDM
29#include <sys/stat.h>
30#include <sys/types.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
123e8278
MP
97/* wrapper template for a function with one "const char* path" argument */
98#define WRAP_1ARG(rettype, failret, name) \
99TS_EXPORT rettype name(const char *path) \
100{ \
101 const char *p; \
102 char buf[PATH_MAX * 2]; \
103 static rettype (*_fn)(const char*); \
104 \
105 if (!get_rootpath(__func__)) \
106 return failret; \
107 _fn = get_libc_func(#name); \
108 p = trap_path(path, buf); \
109 if (p == NULL) \
110 return failret; \
111 return (*_fn)(p); \
6afc9cd6 112}
7fa8c2d2 113
123e8278
MP
114/* wrapper template for a function with "const char* path" and another argument */
115#define WRAP_2ARGS(rettype, failret, name, arg2t) \
116TS_EXPORT rettype name(const char *path, arg2t arg2) \
117{ \
118 const char *p; \
119 char buf[PATH_MAX * 2]; \
120 static rettype (*_fn)(const char*, arg2t arg2); \
121 \
122 if (!get_rootpath(__func__)) \
123 return failret; \
124 _fn = get_libc_func(#name); \
125 p = trap_path(path, buf); \
126 if (p == NULL) \
127 return failret; \
128 return (*_fn)(p, arg2); \
7fa8c2d2 129}
1426a613 130
123e8278
MP
131/* wrapper template for open family */
132#define WRAP_OPEN(suffix) \
133TS_EXPORT int open ## suffix (const char *path, int flags, ...) \
134{ \
135 const char *p; \
136 char buf[PATH_MAX * 2]; \
137 static int (*_fn)(const char *path, int flags, ...); \
138 \
139 if (!get_rootpath(__func__)) \
140 return -1; \
141 _fn = get_libc_func("open" #suffix); \
142 p = trap_path(path, buf); \
143 if (p == NULL) \
144 return -1; \
145 \
146 if (flags & O_CREAT) { \
147 mode_t mode; \
148 va_list ap; \
149 \
150 va_start(ap, flags); \
151 mode = va_arg(ap, mode_t); \
152 va_end(ap); \
153 return _fn(p, flags, mode); \
154 } \
155 \
156 return _fn(p, flags); \
113d0084
LDM
157}
158
123e8278
MP
159/* wrapper template for __xstat family */
160#define WRAP_VERSTAT(prefix, suffix) \
161TS_EXPORT int prefix ## stat ## suffix (int ver, \
162 const char *path, \
163 struct stat ## suffix *st) \
164{ \
165 const char *p; \
166 char buf[PATH_MAX * 2]; \
167 static int (*_fn)(int ver, const char *path, \
168 struct stat ## suffix *); \
169 _fn = get_libc_func(#prefix "stat" #suffix); \
170 \
171 if (!get_rootpath(__func__)) \
172 return -1; \
173 p = trap_path(path, buf); \
174 if (p == NULL) \
175 return -1; \
176 \
177 return _fn(ver, p, st); \
1426a613
LDM
178}
179
123e8278 180WRAP_1ARG(DIR*, NULL, opendir);
1426a613 181
123e8278
MP
182WRAP_2ARGS(FILE*, NULL, fopen, const char*);
183WRAP_2ARGS(int, -1, mkdir, mode_t);
184WRAP_2ARGS(int, -1, access, int);
185WRAP_2ARGS(int, -1, stat, struct stat*);
123e8278 186WRAP_2ARGS(int, -1, lstat, struct stat*);
d6423417
LDM
187#ifndef _FILE_OFFSET_BITS
188WRAP_2ARGS(int, -1, stat64, struct stat64*);
123e8278 189WRAP_2ARGS(int, -1, lstat64, struct stat64*);
d6423417
LDM
190WRAP_OPEN(64);
191#endif
1426a613 192
123e8278 193WRAP_OPEN();
1426a613 194
123e8278
MP
195#ifdef HAVE___XSTAT
196WRAP_VERSTAT(__x,);
123e8278 197WRAP_VERSTAT(__lx,);
d6423417
LDM
198#ifndef _FILE_OFFSET_BITS
199WRAP_VERSTAT(__x,64);
123e8278 200WRAP_VERSTAT(__lx,64);
d005aeb7 201#endif
d6423417 202#endif