/
githubmirror
/
kmod
Обзор
Документация
Войти
/
githubmirror
/
kmod
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
testsuite/path.c
197 строк
7 KB
Emil Velikov
Remove double-space in Copyright boilerplate
28 июл 2026, 17:11
28 июл 2026, 17:11
30d2108
Код
Авторство
О чём код?
// 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 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]) { static const char *rootpath; static size_t rootpathlen; size_t len; if (!need_trap(path)) return path; len = strlen(path); if (rootpath == NULL) { rootpath = getenv(S_TC_ROOTFS); if (rootpath == NULL) { TS_ERR("TRAP: missing export %s?\n", S_TC_ROOTFS); errno = ENOENT; return NULL; } rootpathlen = strlen(rootpath); } if (len + rootpathlen > PATH_MAX * 2) { errno = ENAMETOOLONG; return NULL; } memcpy(buf, rootpath, rootpathlen); strcpy(buf + rootpathlen, path); return buf; } static void *get_libc_func(const char *f) { void *fp; fp = dlsym(RTLD_NEXT, f); if (fp == NULL) { fprintf(stderr, "FIXME FIXME FIXME: could not load %s symbol: %s\n", f, dlerror()); abort(); } 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 *); \ \ p = trap_path(path, buf); \ if (p == NULL) \ return failret; \ \ if (_fn == NULL) \ _fn = get_libc_func(#name); \ 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); \ \ p = trap_path(path, buf); \ if (p == NULL) \ return failret; \ \ if (_fn == NULL) \ _fn = get_libc_func(#name); \ 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, ...); \ \ p = trap_path(path, buf); \ if (p == NULL) \ return -1; \ \ if (_fn == NULL) \ _fn = get_libc_func("open" #suffix); \ 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 *); \ \ p = trap_path(path, buf); \ if (p == NULL) \ return -1; \ \ if (_fn == NULL) \ _fn = get_libc_func(#prefix "stat" #suffix); \ return _fn(ver, p, st); \ } WRAP_1ARG(DIR *, NULL, opendir); WRAP_1ARG(int, -1, chdir); WRAP_1ARG(int, -1, remove); WRAP_1ARG(int, -1, rmdir); WRAP_2ARGS(FILE *, NULL, fopen, const char *); WRAP_2ARGS(int, -1, mkdir, mode_t); WRAP_2ARGS(int, -1, stat, struct stat *); WRAP_OPEN(); #if HAVE_FOPEN64 WRAP_2ARGS(FILE *, NULL, fopen64, const char *); #endif #if HAVE_STAT64 WRAP_2ARGS(int, -1, stat64, struct stat64 *); #endif #if HAVE___STAT64_TIME64 extern int __stat64_time64(const char *file, void *buf); WRAP_2ARGS(int, -1, __stat64_time64, void *); #endif #if HAVE_OPEN64 WRAP_OPEN(64); #endif #if HAVE_DECL___XSTAT WRAP_VERSTAT(__x, ); WRAP_VERSTAT(__x, 64); #endif