// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include #include #include #include #include #include #include #include #include #include namespace { constexpr auto ENV_NAME = "IOSYSCALLS_REDIRECT_TO_IMAGE"; constexpr auto FIRST_FILEDESC = 64'566'756; bool g_readed = false; bool g_redirect = false; constexpr const char * LINUX_PATHS[] { "/dev/", "/etc/", "/usr/share", "/run/user", "/home", "/proc", "/dev/shm", "PurePhone.img", "MuditaOS.log", nullptr }; constexpr const char * IMAGE_PATHS[] { "/sys", nullptr }; pthread_mutex_t g_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; phmap::flat_hash_set g_fdlist; phmap::flat_hash_set g_dirlist; } namespace vfsn::linux::internal { bool redirect_to_image() { if(!g_readed) { const auto env = std::getenv(ENV_NAME); g_redirect = env && !std::strcmp(env,"1"); g_readed = true; } return g_redirect; } bool redirect_to_image(const char* inpath) { if (!redirect_to_image()) return false; for(auto path=LINUX_PATHS; *path; ++path) if( std::strstr(inpath,*path)==inpath) return false; return true; } const char* npath_translate(const char* inpath, char *buffer) { for(auto path=IMAGE_PATHS; *path; ++path) if(std::strstr(inpath, *path) == inpath) { std::strncpy(buffer, inpath + 1, PATH_MAX); return buffer; } return inpath; } bool is_image_handle(const FILE* fil) { return false; } int to_native_fd(int fd) { return FIRST_FILEDESC + fd; } int to_image_fd(int fd) { return fd - FIRST_FILEDESC; } bool is_image_fd(int fd) { return fd >= FIRST_FILEDESC; } FILEX* allocate_filex(int fd) { auto ret = new FILEX; ret->fd = fd; pthread_mutex_lock(&g_lock); g_fdlist.emplace( ret ); pthread_mutex_unlock(&g_lock); return ret; } void add_DIR_to_image_list(DIR* indir) { pthread_mutex_lock(&g_lock); g_dirlist.emplace( indir ); pthread_mutex_unlock(&g_lock); } void remove_DIR_from_image_list(DIR* indir) { pthread_mutex_lock(&g_lock); auto fres = g_dirlist.find(indir); if(fres != g_dirlist.end()) { g_dirlist.erase(fres); } pthread_mutex_unlock(&g_lock); } bool is_image_DIR(DIR* indir) { if(indir==nullptr) { return false; } pthread_mutex_lock(&g_lock); auto fres = g_dirlist.find(indir); auto isntdir = ( fres != g_dirlist.end() ); pthread_mutex_unlock(&g_lock); return isntdir; } bool is_filex(const void* fd) { if(fd==nullptr) { return false; } pthread_mutex_lock(&g_lock); auto fres = g_fdlist.find(reinterpret_cast(fd)); auto isfilex = ( fres != g_fdlist.end() ); pthread_mutex_unlock(&g_lock); return isfilex; } void remove_filex(FILEX *fil) { pthread_mutex_lock(&g_lock); auto fres = g_fdlist.find(fil); if(fres != g_fdlist.end()) { g_fdlist.erase(fres); delete fil; } pthread_mutex_unlock(&g_lock); } void debug_trace_syscall(const char* fn, const char* format, ...) { auto rvprint = reinterpret_cast(dlsym(RTLD_NEXT, "vfprintf")); auto rprint = reinterpret_cast(dlsym(RTLD_NEXT, "fprintf")); rprint(stderr,">>>>>>> IOFUNC: [%s] ", fn); va_list args; va_start(args, format); rvprint(stderr, format, args); va_end(args); rprint(stderr," >>>>>>>>>>>\n"); } }