/
githubmirror
/
kmod
Обзор
Документация
Войти
/
githubmirror
/
kmod
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
v34.1
testsuite/path.c
209 строк
7 KB
Emil Velikov
Revert "testsuite/path: match the full rootpath"
08 ноя 2024, 20:51
08 ноя 2024, 20:51
ebbca1c
Код
Авторство
О чём код?
// SPDX-License-Identifier: LGPL-2.1-or-later /* * Copyright (C) 2012-2013 ProFUSION embedded systems */ /* We unset _FILE_OFFSET_BITS here so we can override both stat and stat64 on * 32-bit architectures and forward each to the right libc function */ #undef _FILE_OFFSET_BITS #undef _TIME_BITS #include <assert.h> #include <dirent.h> #include <dlfcn.h> #include <errno.h> #include <fcntl.h> #include <limits.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <shared/util.h> #include "testsuite.h" static void *nextlib; static const char *rootpath; static size_t rootpathlen; static inline bool need_trap(const char *path) { /* * Always consider the ABS_TOP_BUILDDIR as the base root of anything we do. * * Changing this to rootpath is tempting but incorrect, since it won't consider * any third-party files managed through this LD_PRELOAD library, eg coverage. * * In other words: if using rootpath, the coverage gcna files will end up created * in the wrong location eg. $rootpath/$ABS_TOP_BUILDDIR. */ return path != NULL && path[0] == '/' && !strstartswith(path, ABS_TOP_BUILDDIR); } static const char *trap_path(const char *path, char buf[PATH_MAX * 2]) { size_t len; if (!need_trap(path)) return path; len = strlen(path); if (len + rootpathlen > PATH_MAX * 2) { errno = ENAMETOOLONG; return NULL; } memcpy(buf, rootpath, rootpathlen); strcpy(buf + rootpathlen, path); return buf; } static bool get_rootpath(const char *f) { if (rootpath != NULL) return true; rootpath = getenv(S_TC_ROOTFS); if (rootpath == NULL) { ERR("TRAP %s(): missing export %s?\n", f, S_TC_ROOTFS); errno = ENOENT; return false; } rootpathlen = strlen(rootpath); return true; } static void *get_libc_func(const char *f) { void *fp; if (nextlib == NULL) { #ifdef RTLD_NEXT nextlib = RTLD_NEXT; #else nextlib = dlopen("libc.so.6", RTLD_LAZY); #endif } fp = dlsym(nextlib, f); assert(fp); return fp; } /* wrapper template for a function with one "const char* path" argument */ #define WRAP_1ARG(rettype, failret, name) \ TS_EXPORT rettype name(const char *path) \ { \ const char *p; \ char buf[PATH_MAX * 2]; \ static rettype (*_fn)(const char *); \ \ if (!get_rootpath(__func__)) \ return failret; \ _fn = get_libc_func(#name); \ p = trap_path(path, buf); \ if (p == NULL) \ return failret; \ return (*_fn)(p); \ } /* wrapper template for a function with "const char* path" and another argument */ #define WRAP_2ARGS(rettype, failret, name, arg2t) \ TS_EXPORT rettype name(const char *path, arg2t arg2) \ { \ const char *p; \ char buf[PATH_MAX * 2]; \ static rettype (*_fn)(const char *, arg2t arg2); \ \ if (!get_rootpath(__func__)) \ return failret; \ _fn = get_libc_func(#name); \ p = trap_path(path, buf); \ if (p == NULL) \ return failret; \ return (*_fn)(p, arg2); \ } /* wrapper template for open family */ #define WRAP_OPEN(suffix) \ TS_EXPORT int open##suffix(const char *path, int flags, ...) \ { \ const char *p; \ char buf[PATH_MAX * 2]; \ static int (*_fn)(const char *path, int flags, ...); \ \ if (!get_rootpath(__func__)) \ return -1; \ _fn = get_libc_func("open" #suffix); \ p = trap_path(path, buf); \ if (p == NULL) \ return -1; \ \ if (flags & O_CREAT) { \ mode_t mode; \ va_list ap; \ \ va_start(ap, flags); \ mode = va_arg(ap, mode_t); \ va_end(ap); \ return _fn(p, flags, mode); \ } \ \ return _fn(p, flags); \ } #define WRAP_VERSTAT(prefix, suffix) \ TS_EXPORT int prefix##stat##suffix(int ver, const char *path, \ struct stat##suffix *st) \ { \ const char *p; \ char buf[PATH_MAX * 2]; \ static int (*_fn)(int ver, const char *path, struct stat##suffix *); \ _fn = get_libc_func(#prefix "stat" #suffix); \ \ if (!get_rootpath(__func__)) \ return -1; \ p = trap_path(path, buf); \ if (p == NULL) \ return -1; \ \ return _fn(ver, p, st); \ } WRAP_1ARG(DIR *, NULL, opendir); WRAP_1ARG(int, -1, chdir); WRAP_2ARGS(FILE *, NULL, fopen, const char *); WRAP_2ARGS(int, -1, mkdir, mode_t); WRAP_2ARGS(int, -1, stat, struct stat *); WRAP_OPEN(); #ifdef HAVE_FOPEN64 WRAP_2ARGS(FILE *, NULL, fopen64, const char *); #endif #ifdef HAVE_STAT64 WRAP_2ARGS(int, -1, stat64, struct stat64 *); #endif #ifdef HAVE___STAT64_TIME64 extern int __stat64_time64(const char *file, void *buf); WRAP_2ARGS(int, -1, __stat64_time64, void *); #endif #ifdef HAVE_OPEN64 WRAP_OPEN(64); #endif #if HAVE_DECL___XSTAT WRAP_VERSTAT(__x, ); WRAP_VERSTAT(__x, 64); #endif