@@ 1,209 1,277 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <iosyscalls.hpp>
+
+#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <dlfcn.h>
#include <fcntl.h>
+
+#include <errno.h>
+
+#include <stdarg.h> // for va_*
+#include <limits.h> // for PATH_MAX
+#include <dlfcn.h> // for dlsym()
+
#include <stdio.h>
-#include <stdlib.h>
-#include <cstring>
-#include <stdarg.h>
-#include <limits.h>
-#include "debug.hpp"
#include <purefs/fs/filesystem.hpp>
+#include "debug.hpp"
+
+#define __REAL_DECL(fun) decltype(::fun) *fun
+#define __REAL_DLSYM(fun) real::fun = reinterpret_cast<decltype(real::fun)>(dlsym(RTLD_NEXT, #fun))
+
+#define __VFS(fun) (&purefs::fs::filesystem::fun)
namespace
{
- int (*real_fprintf)(FILE *__restrict __stream, const char *__restrict __format, ...);
+ namespace real {
+ __REAL_DECL(link);
+ __REAL_DECL(unlink);
+
+ __REAL_DECL(fcntl);
+ __REAL_DECL(fcntl64);
+
+ __REAL_DECL(chdir);
+ __REAL_DECL(fchdir);
+
+ __REAL_DECL(getcwd);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ __REAL_DECL(getwd);
+#pragma GCC diagnostic pop
+
+ __REAL_DECL(get_current_dir_name);
+ __REAL_DECL(mkdir);
+
+ __REAL_DECL(chmod);
+ __REAL_DECL(fchmod);
+ __REAL_DECL(fsync);
+ __REAL_DECL(symlink);
+
+ __REAL_DECL(__xstat);
+ __REAL_DECL(__lxstat);
+ __REAL_DECL(__fxstat);
+
+ __REAL_DECL(__xstat64);
+ __REAL_DECL(__lxstat64);
+ __REAL_DECL(__fxstat64);
+
+ __REAL_DECL(rename);
+ } // namespace real
void __attribute__((constructor)) _lib_posix_initialize()
{
- real_fprintf = reinterpret_cast<decltype(real_fprintf)>(dlsym(RTLD_NEXT, "fprintf"));
- if(!real_fprintf)
+ __REAL_DLSYM(link);
+ __REAL_DLSYM(unlink);
+
+ __REAL_DLSYM(fcntl);
+ __REAL_DLSYM(fcntl64);
+
+ __REAL_DLSYM(chdir);
+ __REAL_DLSYM(fchdir);
+
+ __REAL_DLSYM(getcwd);
+ __REAL_DLSYM(getwd);
+ __REAL_DLSYM(get_current_dir_name);
+ __REAL_DLSYM(mkdir);
+
+ __REAL_DLSYM(chmod);
+ __REAL_DLSYM(fchmod);
+ __REAL_DLSYM(fsync);
+ __REAL_DLSYM(symlink);
+
+ __REAL_DLSYM(__xstat);
+ __REAL_DLSYM(__lxstat);
+ __REAL_DLSYM(__fxstat);
+
+ __REAL_DLSYM(__xstat64);
+ __REAL_DLSYM(__lxstat64);
+ __REAL_DLSYM(__fxstat64);
+
+ __REAL_DLSYM(rename);
+
+ if (!(real::link && real::unlink
+ && real::fcntl && real::fcntl64 && real::chdir && real::fchdir
+ && real::getcwd && real::getwd && real::get_current_dir_name && real::mkdir
+ && real::chmod && real::chdir && real::fchdir && real::fsync && real::symlink
+ && real::__xstat && real::__lxstat && real::__fxstat
+ && real::__xstat64 && real::__lxstat64 && real::__fxstat64
+ && real::rename))
{
abort();
}
}
-}
+} //namespace
extern "C" {
- using namespace vfsn::linux::internal;
- int link(const char *oldpath, const char *newpath)
+ namespace vfs = vfsn::linux::internal;
+
+ int _iosys_link(const char *oldpath, const char *newpath)
{
TRACE_SYSCALL();
- if(redirect_to_image(oldpath))
+ if(vfs::redirect_to_image(oldpath))
{
errno = ENOSYS;
- real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
+ std::cerr << "Unsupported syscall " << __PRETTY_FUNCTION__ << std::endl;
return -1;
}
else
{
- auto r_link = reinterpret_cast<int (*)(const char*,const char*)>(dlsym(RTLD_NEXT,"link"));
char tmp[PATH_MAX], tmp2[PATH_MAX];
- const auto oldp = npath_translate(oldpath,tmp);
- const auto newp = npath_translate(newpath,tmp2);
- return r_link(oldp,newp);
+ const auto oldp = vfs::npath_translate(oldpath,tmp);
+ const auto newp = vfs::npath_translate(newpath,tmp2);
+ return real::link(oldp,newp);
}
}
- __asm__(".symver link,link@GLIBC_2.2.5");
+ __asm__(".symver _iosys_link,link@GLIBC_2.2.5");
- int unlink(const char *name)
+ int _iosys_unlink(const char *name)
{
TRACE_SYSCALL();
- if(redirect_to_image(name))
+ if(vfs::redirect_to_image(name))
{
- return invoke_fs(&purefs::fs::filesystem::unlink, name);
+ return vfs::invoke_fs(__VFS(unlink), name);
}
else
{
char tmp[PATH_MAX];
- const auto path = npath_translate(name,tmp);
- auto r_unlink = reinterpret_cast<int (*)(const char*)>(dlsym(RTLD_NEXT,"unlink"));
- return r_unlink(path);
+ const auto path = vfs::npath_translate(name,tmp);
+ return real::unlink(path);
}
}
- __asm__(".symver unlink,unlink@GLIBC_2.2.5");
+ __asm__(".symver _iosys_unlink,unlink@GLIBC_2.2.5");
- int stat(const char *file, struct stat *pstat)
+ int _iosys_stat(const char *file, struct stat *pstat)
{
TRACE_SYSCALL();
- if(redirect_to_image(file))
+ if(vfs::redirect_to_image(file))
{
- return invoke_fs(&purefs::fs::filesystem::stat, file, *pstat);
+ return vfs::invoke_fs(__VFS(stat), file, *pstat);
}
else
{
char tmp[PATH_MAX];
- const auto newfile = npath_translate(file,tmp);
- auto r_xstat = reinterpret_cast<int (*)(int, const char*,struct stat*)>(dlsym(RTLD_NEXT, "__xstat"));
- return r_xstat(1,newfile,pstat);
+ const auto newfile = vfs::npath_translate(file,tmp);
+ return real::__xstat(1,newfile,pstat);
}
}
- __asm__(".symver stat,stat@GLIBC_2.2.5");
+ __asm__(".symver _iosys_stat,stat@GLIBC_2.2.5");
- int fstat(int fd, struct stat *pstat)
+ int _iosys_lstat(const char *pathname, struct stat *statbuf)
{
TRACE_SYSCALL();
- if(is_image_fd(fd))
+ if(vfs::redirect_to_image(pathname))
{
- return invoke_fs(&purefs::fs::filesystem::fstat,fd,*pstat);
+ return vfs::invoke_fs(__VFS(stat), pathname, *statbuf);
}
else
{
- auto r_fxstat = reinterpret_cast<int (*)(int, int, struct stat*)>(dlsym(RTLD_NEXT, "__fxstat"));
- return r_fxstat(1,fd,pstat);
+ char tmp[PATH_MAX];
+ const auto newpath = vfs::npath_translate(pathname,tmp);
+ return real::__lxstat(1,newpath,statbuf);
}
}
- __asm__(".symver fstat,fstat@GLIBC_2.2.5");
+ __asm__(".symver _iosys_lstat,lstat@GLIBC_2.2.5");
- int lstat(const char *pathname, struct stat *statbuf)
+ int _iosys_fstat(int fd, struct stat *pstat)
{
TRACE_SYSCALL();
- if(redirect_to_image(pathname))
+ if(vfs::is_image_fd(fd))
{
- return invoke_fs(&purefs::fs::filesystem::stat, pathname, *statbuf);
+ return vfs::invoke_fs(__VFS(fstat),fd,*pstat);
}
else
{
- char tmp[PATH_MAX];
- const auto newpath = npath_translate(pathname,tmp);
- auto r_lxstat = reinterpret_cast<int (*)(int, const char*,struct stat*)>(dlsym(RTLD_NEXT, "__lxstat"));
- return r_lxstat(1,newpath,statbuf);
+ return real::__fxstat(1,fd,pstat);
}
}
- __asm__(".symver lstat,lstat@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fstat,fstat@GLIBC_2.2.5");
- int fcntl(int fd, int cmd, ... /* arg */ )
+ int _iosys_fcntl(int fd, int cmd, ... /* arg */ )
{
TRACE_SYSCALL();
- if(is_image_fd(fd))
+ if(vfs::is_image_fd(fd))
{
- TRACE_SYSCALL();
errno = ENOSYS;
- real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
+ std::cerr << "Unsupported syscall " << __PRETTY_FUNCTION__ << std::endl;
return -1;
}
else
{
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
uintptr_t param;
va_list args;
- auto r_fcntl = reinterpret_cast<int (*)(int,int,...)>(dlsym(RTLD_NEXT, "fcntl"));
va_start(args,cmd);
param = va_arg(args,uintptr_t);
- auto ret = r_fcntl(fd, cmd, param );
+ auto ret = real::fcntl(fd, cmd, param );
va_end(args);
return ret;
}
}
- __asm__(".symver fcntl,fcntl@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fcntl,fcntl@GLIBC_2.2.5");
- int fcntl64(int fd, int cmd, ... /* arg */ )
+ int _iosys_fcntl64(int fd, int cmd, ... /* arg */ )
{
TRACE_SYSCALL();
- if(is_image_fd(fd))
+ if(vfs::is_image_fd(fd))
{
- TRACE_SYSCALL();
- real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
errno = ENOSYS;
+ std::cerr << "Unsupported syscall " << __PRETTY_FUNCTION__ << std::endl;
return -1;
} else {
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
uintptr_t param;
va_list args;
- auto r_fcntl = reinterpret_cast<int (*)(int,int,...)>(dlsym(RTLD_NEXT, "fcntl64"));
va_start(args,cmd);
param = va_arg(args,uintptr_t);
- auto ret = r_fcntl(fd, cmd, param);
+ auto ret = real::fcntl64(fd, cmd, param);
va_end(args);
return ret;
}
}
- __asm__(".symver fcntl64,fcntl64@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fcntl64,fcntl64@GLIBC_2.2.5");
- int chdir(const char *path)
+ int _iosys_chdir(const char *path)
{
TRACE_SYSCALL();
- if(redirect_to_image(path))
+ if(vfs::redirect_to_image(path))
{
- return invoke_fs(&purefs::fs::filesystem::chdir, path);
+ return vfs::invoke_fs(__VFS(chdir), path);
}
else
{
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
char tmp[PATH_MAX];
- const auto newpath = npath_translate(path,tmp);
- auto r_chdir = reinterpret_cast<int(*)(const char*)>(dlsym(RTLD_NEXT,"chdir"));
- return r_chdir(newpath);
+ const auto newpath = vfs::npath_translate(path,tmp);
+ return real::chdir(newpath);
}
}
- __asm__(".symver chdir,chdir@GLIBC_2.2.5");
+ __asm__(".symver _iosys_chdir,chdir@GLIBC_2.2.5");
- int fchdir(int fd)
+ int _iosys_fchdir(int fd)
{
TRACE_SYSCALL();
- if(is_image_fd(fd))
+ if(vfs::is_image_fd(fd))
{
errno = ENOSYS;
- real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
+ std::cerr << "Unsupported syscall " << __PRETTY_FUNCTION__ << std::endl;
return -1;
}
else
{
- auto r_fchdir = reinterpret_cast<int(*)(int)>(dlsym(RTLD_NEXT,"fchdir"));
- return r_fchdir(fd);
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
+ return real::fchdir(fd);
}
}
- __asm__(".symver fchdir,fchdir@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fchdir,fchdir@GLIBC_2.2.5");
- char *getcwd(char *buf, size_t size)
+ char *_iosys_getcwd(char *buf, size_t size)
{
TRACE_SYSCALL();
- if(redirect_to_image())
+ if(vfs::redirect_to_image())
{
auto vfs = purefs::subsystem::vfs_core();
if(!vfs) {
@@ 216,16 284,16 @@ extern "C" {
}
else
{
- auto r_getcwd = reinterpret_cast<char*(*)(char*,size_t)>(dlsym(RTLD_NEXT,"getcwd"));
- return r_getcwd(buf,size);
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
+ return real::getcwd(buf,size);
}
}
- __asm__(".symver getcwd,getcwd@GLIBC_2.2.5");
+ __asm__(".symver _iosys_getcwd,getcwd@GLIBC_2.2.5");
- char *getwd(char *buf)
+ char *_iosys_getwd(char *buf)
{
TRACE_SYSCALL();
- if(redirect_to_image())
+ if(vfs::redirect_to_image())
{
auto vfs = purefs::subsystem::vfs_core();
if(!vfs) {
@@ 238,17 306,17 @@ extern "C" {
}
else
{
- auto r_getwd = reinterpret_cast<char*(*)(char*)>(dlsym(RTLD_NEXT,"getwd"));
- return r_getwd(buf);
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
+ return real::getwd(buf);
}
}
- __asm__(".symver getwd,getwd@GLIBC_2.2.5");
+ __asm__(".symver _iosys_getwd,getwd@GLIBC_2.2.5");
- char *get_current_dir_name(void)
+ char *_iosys_get_current_dir_name(void)
{
TRACE_SYSCALL();
- if(redirect_to_image())
+ if(vfs::redirect_to_image())
{
auto vfs = purefs::subsystem::vfs_core();
if(!vfs) {
@@ 263,176 331,223 @@ extern "C" {
}
else
{
- auto r_getrd = reinterpret_cast<char*(*)()>(dlsym(RTLD_NEXT,"get_current_dir_name"));
- return r_getrd();
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
+ return real::get_current_dir_name();
}
}
- __asm__(".symver get_current_dir_name,get_current_dir_name@GLIBC_2.2.5");
+ __asm__(".symver _iosys_get_current_dir_name,get_current_dir_name@GLIBC_2.2.5");
-
- int rename(const char *oldpath, const char *newpath)
+ int _iosys_rename(const char *oldpath, const char *newpath)
{
TRACE_SYSCALL();
- if(redirect_to_image(oldpath))
+ if(vfs::redirect_to_image(oldpath))
{
- return invoke_fs(&purefs::fs::filesystem::rename, oldpath, newpath);
+ return vfs::invoke_fs(__VFS(rename), oldpath, newpath);
}
else
{
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
char tmp[PATH_MAX], tmp2[PATH_MAX];
- const auto oldp = npath_translate(oldpath,tmp);
- const auto newp = npath_translate(newpath,tmp2);
- auto r_rename = reinterpret_cast<int(*)(const char*,const char*)>(dlsym(RTLD_NEXT,"rename"));
- return r_rename(oldp,newp);
+ const auto oldp = vfs::npath_translate(oldpath,tmp);
+ const auto newp = vfs::npath_translate(newpath,tmp2);
+ return real::rename(oldp,newp);
}
}
- __asm__(".symver rename,rename@GLIBC_2.2.5");
+ __asm__(".symver _iosys_rename,rename@GLIBC_2.2.5");
- int mkdir(const char *pathname, mode_t mode)
+ int _iosys_mkdir(const char *pathname, mode_t mode)
{
- if(redirect_to_image(pathname))
+ if(vfs::redirect_to_image(pathname))
{
- return invoke_fs(&purefs::fs::filesystem::mkdir, pathname, mode);
+ return vfs::invoke_fs(__VFS(mkdir), pathname, mode);
}
else
{
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
char tmp[PATH_MAX];
- const auto path = npath_translate(pathname,tmp);
- auto r_mkdir = reinterpret_cast<int(*)(const char*,mode_t)>(dlsym(RTLD_NEXT,"mkdir"));
- return r_mkdir(path,mode);
+ const auto path = vfs::npath_translate(pathname,tmp);
+ return real::mkdir(path,mode);
}
}
- __asm__(".symver mkdir,mkdir@GLIBC_2.2.5");
+ __asm__(".symver _iosys_mkdir,mkdir@GLIBC_2.2.5");
- int chmod(const char *pathname, mode_t mode)
+ int _iosys_chmod(const char *pathname, mode_t mode)
{
TRACE_SYSCALL();
- if(redirect_to_image(pathname))
+ if(vfs::redirect_to_image(pathname))
{
- return invoke_fs(&purefs::fs::filesystem::chmod,pathname,mode);
+ return vfs::invoke_fs(__VFS(chmod),pathname,mode);
}
else
{
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
char tmp[PATH_MAX];
- const auto path = npath_translate(pathname,tmp);
- auto r_chmod = reinterpret_cast<int(*)(const char*,mode_t)>(dlsym(RTLD_NEXT,"chmod"));
- return r_chmod(path,mode);
+ const auto path = vfs::npath_translate(pathname,tmp);
+ return real::chmod(path,mode);
}
}
- __asm__(".symver chmod,chmod@GLIBC_2.2.5");
+ __asm__(".symver _iosys_chmod,chmod@GLIBC_2.2.5");
- int fchmod(int fd, mode_t mode)
+ int _iosys_fchmod(int fd, mode_t mode)
{
TRACE_SYSCALL();
- if(is_image_fd(fd))
+ if(vfs::is_image_fd(fd))
{
- return invoke_fs(&purefs::fs::filesystem::fchmod,fd,mode);
+ return vfs::invoke_fs(__VFS(fchmod),fd,mode);
}
else
{
- auto r_fchmod = reinterpret_cast<int(*)(int,mode_t)>(dlsym(RTLD_NEXT,"fchmod"));
- return r_fchmod(fd,mode);
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
+ return real::fchmod(fd,mode);
}
}
- __asm__(".symver fchmod,fchmod@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fchmod,fchmod@GLIBC_2.2.5");
- int fsync(int fd)
+ int _iosys_fsync(int fd)
{
TRACE_SYSCALL();
- if(is_image_fd(fd))
+ if(vfs::is_image_fd(fd))
{
- return invoke_fs(&purefs::fs::filesystem::fsync, fd);
+ return vfs::invoke_fs(__VFS(fsync), fd);
}
else
{
- auto r_fsync = reinterpret_cast<int(*)(int)>(dlsym(RTLD_NEXT,"fsync"));
- return r_fsync(fd);
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
+ return real::fsync(fd);
}
}
- __asm__(".symver fsync,fsync@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fsync,fsync@GLIBC_2.2.5");
- int fdatasync(int fd)
+ int _iosys_fdatasync(int fd)
{
TRACE_SYSCALL();
return fsync(fd);
}
- __asm__(".symver fdatasync,fdatasync@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fdatasync,fdatasync@GLIBC_2.2.5");
- int symlink(const char *target, const char *linkpath)
+ int _iosys_symlink(const char *target, const char *linkpath)
{
TRACE_SYSCALL();
- if(redirect_to_image(target))
+ if(vfs::redirect_to_image(target))
{
- return invoke_fs(&purefs::fs::filesystem::symlink,target,linkpath);
+ return vfs::invoke_fs(__VFS(symlink),target,linkpath);
}
else
{
+ TRACE_SYSCALLN("%s", "Redirecting to linux fs");
char tmp[PATH_MAX], tmp2[PATH_MAX];
- const auto tgtp = npath_translate(target,tmp);
- const auto linp = npath_translate(linkpath,tmp2);
- auto r_symlink = reinterpret_cast<int(*)(const char*,const char*)>(dlsym(RTLD_NEXT,"symlink"));
- return r_symlink(tgtp,linp);
+ const auto tgtp = vfs::npath_translate(target,tmp);
+ const auto linp = vfs::npath_translate(linkpath,tmp2);
+ return real::symlink(tgtp,linp);
}
}
+ __asm__(".symver _iosys_symlink,symlink@GLIBC_2.2.5");
- __asm__(".symver symlink,symlink@GLIBC_2.2.5");
+ int _iosys_xstat(int ver, const char * path, struct stat * stat_buf)
+ {
+ if(vfs::redirect_to_image(path))
+ {
+ return vfs::invoke_fs(__VFS(stat), path, *stat_buf);
+ }
+ else
+ {
+ TRACE_SYSCALLN("(%s) -> linux fs", path);
+ char tmp[PATH_MAX];
+ const auto newp = vfs::npath_translate(path,tmp);
+ return real::__xstat(ver,newp,stat_buf);
+ }
+ }
+ __asm__(".symver _iosys_xstat,__xstat@GLIBC_2.2.5");
- int __symlink(const char *target, const char *linkpath)
+ int _iosys_lxstat(int ver, const char * path, struct stat * stat_buf)
{
- return symlink(target,linkpath);
+ if(vfs::redirect_to_image(path))
+ {
+ return vfs::invoke_fs(__VFS(stat), path, *stat_buf);
+ }
+ else
+ {
+ TRACE_SYSCALLN("(%s) -> linux fs", path);
+ char tmp[PATH_MAX];
+ const auto newp = vfs::npath_translate(path,tmp);
+ return real::__lxstat(ver,newp,stat_buf);
+ }
}
+ __asm__(".symver _iosys_lxstat,__lxstat@GLIBC_2.2.5");
+ int _iosys_fxstat(int ver, int fildes, struct stat * stat_buf)
+ {
+ if(vfs::is_image_fd(fildes))
+ {
+ return vfs::invoke_fs(__VFS(fstat), fildes, *stat_buf);
+ }
+ else
+ {
+ TRACE_SYSCALLN("(%d) -> linux fs", fildes);
+ return real::__fxstat(ver,fildes,stat_buf);
+ }
+ }
+ __asm__(".symver _iosys_fxstat,__fxstat@GLIBC_2.2.5");
- int fstatat(int dirfd, const char *pathname, struct stat *statbuf,
- int flags)
+ int _iosys_fxstatat(int vers, int fd, const char *filename, struct stat *buf, int flag)
{
- TRACE_SYSCALL();
errno = ENOSYS;
- real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
+ std::cerr << "Unsupported syscall " << __PRETTY_FUNCTION__ << std::endl;
return -1;
}
- __asm__(".symver fstatat,fstatat@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fxstatat,__fxstatat@GLIBC_2.2.5");
- int __xstat(int ver, const char * path, struct stat * stat_buf)
+ int _iosys_xstat64(int ver, const char * path, struct stat64 * stat_buf)
{
- if( redirect_to_image(path) )
+ if(vfs::redirect_to_image(path))
{
- return invoke_fs(&purefs::fs::filesystem::stat, path, *stat_buf);
+ return vfs::invoke_fs(__VFS(stat), path, *(struct stat*)stat_buf);
}
else
{
+ TRACE_SYSCALLN("(%s) -> linux fs", path);
char tmp[PATH_MAX];
- const auto newp = npath_translate(path,tmp);
- auto r_xstat = reinterpret_cast<int (*)(int,const char*,struct stat*)>(dlsym(RTLD_NEXT, "__xstat"));
- return r_xstat(ver,newp,stat_buf);
+ const auto newp = vfs::npath_translate(path,tmp);
+ return real::__xstat64(ver,newp,stat_buf);
}
}
+ __asm__(".symver _iosys_xstat64,__xstat64@GLIBC_2.2.5");
- int __lxstat(int ver, const char * path, struct stat * stat_buf)
+ int _iosys_lxstat64(int ver, const char * path, struct stat64 * stat_buf)
{
- if( redirect_to_image(path) )
+ if(vfs::redirect_to_image(path))
{
- return invoke_fs(&purefs::fs::filesystem::stat, path, *stat_buf);
+ return vfs::invoke_fs(__VFS(stat), path, *(struct stat*)stat_buf);
}
else
{
+ TRACE_SYSCALLN("(%s) -> linux fs", path);
char tmp[PATH_MAX];
- const auto newp = npath_translate(path,tmp);
- auto r_xstat = reinterpret_cast<int (*)(int,const char*,struct stat*)>(dlsym(RTLD_NEXT, "__lxstat"));
- return r_xstat(ver,newp,stat_buf);
+ const auto newp = vfs::npath_translate(path,tmp);
+ return real::__lxstat64(ver,newp,stat_buf);
}
}
+ __asm__(".symver _iosys_lxstat64,__lxstat64@GLIBC_2.2.5");
- int __fxstat(int ver, int fildes, struct stat * stat_buf)
+ int _iosys_fxstat64(int ver, int fildes, struct stat64 * stat_buf)
{
- if( is_image_fd(fildes) )
+ if(vfs::is_image_fd(fildes))
{
- return invoke_fs(&purefs::fs::filesystem::fstat, fildes, *stat_buf);
+ return vfs::invoke_fs(__VFS(fstat), fildes, *(struct stat*)stat_buf);
}
else
{
- auto r_fxstat = reinterpret_cast<int (*)(int,int,struct stat*)>(dlsym(RTLD_NEXT, "__fxstat"));
- return r_fxstat(ver,fildes,stat_buf);
+ TRACE_SYSCALLN("(%d) -> linux fs", fildes);
+ return real::__fxstat64(ver,fildes,stat_buf);
}
}
+ __asm__(".symver _iosys_fxstat64,__fxstat64@GLIBC_2.2.5");
+
+ int _iosys_fxstatat64(int vers, int fd, const char *filename, struct stat64 *buf, int flag)
+ {
+ errno = ENOSYS;
+ std::cerr << "Unsupported syscall " << __PRETTY_FUNCTION__ << std::endl;
+ return -1;
+ }
+ __asm__(".symver _iosys_fxstatat64,__fxstatat64@GLIBC_2.4");
}
@@ 7,13 7,13 @@
#include <string.h>
#include <mutex>
#include <unordered_map>
-#include <handle_mapper.hpp>
#include <iosyscalls.hpp>
-#include "debug.hpp"
#include <fcntl.h>
#include <stdarg.h>
#include <limits.h>
+#include "debug.hpp"
+
namespace
{
int (*real_fprintf)(FILE *__restrict __stream, const char *__restrict __format, ...);
@@ 112,11 112,12 @@ extern "C"
{
using namespace vfsn::linux::internal;
- FILE *fopen(const char *pathname, const char *mode)
+ FILE *_iosys_fopen(const char *pathname, const char *mode)
{
FILE* ret {};
if(redirect_to_image(pathname))
{
+ TRACE_SYSCALLN("(%s,%s) -> VFS", pathname, mode);
const auto fd = invoke_fs(&purefs::fs::filesystem::open, pathname, fopen_to_open_flags(mode),0644);
if(fd >= 0) {
ret = reinterpret_cast<FILE*>(allocate_filex(fd));
@@ 124,6 125,7 @@ extern "C"
}
else
{
+ TRACE_SYSCALLN("(%s,%s) -> linux fs", pathname, mode);
char tmp[PATH_MAX];
const auto path = npath_translate(pathname,tmp);
ret = real_fopen(path,mode);
@@ 131,19 133,20 @@ extern "C"
TRACE_SYSCALLN("(%s,%s)=%p", pathname, mode, ret);
return ret;
}
- __asm__(".symver fopen,fopen@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fopen,fopen@GLIBC_2.2.5");
- FILE *fopen64(const char *pathname, const char *mode)
+ FILE *_iosys_fopen64(const char *pathname, const char *mode)
{
+ TRACE_SYSCALLN("(%s,%s)", pathname, mode);
return fopen(pathname,mode);
}
- __asm__(".symver fopen64,fopen64@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fopen64,fopen64@GLIBC_2.2.5");
- int fclose(FILE *__stream)
+ int _iosys_fclose(FILE *__stream)
{
- TRACE_SYSCALL();
if(is_filex(__stream))
{
+ TRACE_SYSCALLN("(%p) -> VFS", __stream);
auto fx = reinterpret_cast<FILEX*>(__stream);
auto ret = invoke_fs(&purefs::fs::filesystem::close, fx->fd);
if(!ret)
@@ 158,21 161,22 @@ extern "C"
}
else
{
+ TRACE_SYSCALLN("(%p) -> linux fs", __stream);
return real_fclose(__stream);
}
}
- __asm__(".symver fclose,fclose@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fclose,fclose@GLIBC_2.2.5");
- FILE *fdopen(int __fd, const char *__modes) __THROW
+ FILE *_iosys_fdopen(int __fd, const char *__modes) __THROW
{
TRACE_SYSCALL();
- real_fprintf(stderr, "unimplemented call %s\n", __PRETTY_FUNCTION__);
+ std::cerr << "Unimplemented syscall " << __PRETTY_FUNCTION__ << std::endl;
errno = ENOTSUP;
return nullptr;
}
- __asm__(".symver fdopen,fdopen@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fdopen,fdopen@GLIBC_2.2.5");
- int feof(FILE *__stream) __THROW
+ int _iosys_feof(FILE *__stream) __THROW
{
int ret {};
if(is_filex(__stream))
@@ 204,9 208,9 @@ extern "C"
TRACE_SYSCALLN("(%p)=%i",__stream,ret);
return ret;
}
- __asm__(".symver feof,feof@GLIBC_2.2.5");
+ __asm__(".symver _iosys_feof,feof@GLIBC_2.2.5");
- int ferror(FILE * stream) __THROW
+ int _iosys_ferror(FILE * stream) __THROW
{
TRACE_SYSCALL();
if(is_filex(stream))
@@ 219,9 223,9 @@ extern "C"
return real_ferror(stream);
}
}
- __asm__(".symver ferror,ferror@GLIBC_2.2.5");
+ __asm__(".symver _iosys_ferror,ferror@GLIBC_2.2.5");
- int fflush(FILE *__stream)
+ int _iosys_fflush(FILE *__stream)
{
int ret {};
if(is_filex(__stream))
@@ 237,9 241,9 @@ extern "C"
TRACE_SYSCALLN("(%p)=%i",__stream,ret);
return ret;
}
- __asm__(".symver fflush,fflush@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fflush,fflush@GLIBC_2.2.5");
- int fgetc(FILE *__stream)
+ int _iosys_fgetc(FILE *__stream)
{
TRACE_SYSCALL();
if(is_filex(__stream))
@@ 255,9 259,9 @@ extern "C"
return real_fgetc(__stream);
}
}
- __asm__(".symver fgetc,fgetc@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fgetc,fgetc@GLIBC_2.2.5");
- int fgetpos(FILE *__restrict __stream, fpos_t *__restrict __pos)
+ int _iosys_fgetpos(FILE *__restrict __stream, fpos_t *__restrict __pos)
{
TRACE_SYSCALL();
if(is_filex(__stream))
@@ 275,9 279,9 @@ extern "C"
return real_fgetpos(__stream, __pos);
}
}
- __asm__(".symver fgetpos,fgetpos@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fgetpos,fgetpos@GLIBC_2.2.5");
- int fgetpos64(FILE *__restrict __stream, fpos64_t *__restrict __pos)
+ int _iosys_fgetpos64(FILE *__restrict __stream, fpos64_t *__restrict __pos)
{
TRACE_SYSCALL();
if(is_filex(__stream))
@@ 295,9 299,9 @@ extern "C"
return real_fgetpos64(__stream, __pos);
}
}
- __asm__(".symver fgetpos64,fgetpos64@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fgetpos64,fgetpos64@GLIBC_2.2.5");
- char *fgets(char *__restrict __s, int __n, FILE *__restrict __stream)
+ char *_iosys_fgets(char *__restrict __s, int __n, FILE *__restrict __stream)
{
TRACE_SYSCALL();
if(is_filex(__s))
@@ 327,9 331,9 @@ extern "C"
return real_fgets(__s,__n,__stream);
}
}
- __asm__(".symver fgets,fgets@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fgets,fgets@GLIBC_2.2.5");
- int fileno(FILE *__stream) __THROW
+ int _iosys_fileno(FILE *__stream) __THROW
{
int ret {};
if(is_filex(__stream))
@@ 344,9 348,9 @@ extern "C"
TRACE_SYSCALLN("(%p)=%i",__stream,ret);
return ret;
}
- __asm__(".symver fileno,fileno@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fileno,fileno@GLIBC_2.2.5");
- int fprintf(FILE *__restrict __stream, const char *__restrict __format, ...)
+ int _iosys_fprintf(FILE *__restrict __stream, const char *__restrict __format, ...)
{
constexpr auto buf_len = 4096;
int iCount;
@@ 387,9 391,9 @@ extern "C"
fx->error = errno;
return iCount;
}
- __asm__(".symver fprintf,fprintf@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fprintf,fprintf@GLIBC_2.2.5");
- int fputc(int __c, FILE *__stream)
+ int _iosys_fputc(int __c, FILE *__stream)
{
if(!is_filex(__stream))
{
@@ 405,9 409,9 @@ extern "C"
return ret==1?0:ret;
}
}
- __asm__(".symver fputc,fputc@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fputc,fputc@GLIBC_2.2.5");
- int fputs(const char *__restrict __s, FILE *__restrict __stream)
+ int _iosys_fputs(const char *__restrict __s, FILE *__restrict __stream)
{
int ret {};
if(is_filex(__stream))
@@ 425,9 429,9 @@ extern "C"
TRACE_SYSCALLN("(%s, %p)=%i",__s, __stream, ret);
return ret;
}
- __asm__(".symver fputs,fputs@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fputs,fputs@GLIBC_2.2.5");
- size_t fread(void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream)
+ size_t _iosys_fread(void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream)
{
size_t ret {};
if(__size!=0 && __n!=0)
@@ 454,10 458,10 @@ extern "C"
TRACE_SYSCALLN("(%p, %lu, %lu, %p)=%i",__ptr,__size,__n,__stream, ret);
return ret;
}
- __asm__(".symver fread,fread@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fread,fread@GLIBC_2.2.5");
- FILE *freopen (const char *__restrict __filename,
+ FILE *_iosys_freopen (const char *__restrict __filename,
const char *__restrict __modes,
FILE *__restrict __stream)
{
@@ 473,9 477,9 @@ extern "C"
return fopen(__filename, __modes );
}
}
- __asm__(".symver freopen,freopen@GLIBC_2.2.5");
+ __asm__(".symver _iosys_freopen,freopen@GLIBC_2.2.5");
- int fseek (FILE *__stream, long int __off, int __whence)
+ int _iosys_fseek (FILE *__stream, long int __off, int __whence)
{
int ret {};
if(is_filex(__stream))
@@ 491,9 495,9 @@ extern "C"
TRACE_SYSCALLN("(%p, %li, %i)=%i",__stream,__off,__whence,ret);
return ret;
}
- __asm__(".symver fseek,fseek@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fseek,fseek@GLIBC_2.2.5");
- int fsetpos (FILE *__stream, const fpos_t *__pos)
+ int _iosys_fsetpos (FILE *__stream, const fpos_t *__pos)
{
TRACE_SYSCALL();
if(!is_filex(__stream))
@@ 507,9 511,9 @@ extern "C"
return ret>0?0:ret;
}
}
- __asm__(".symver fsetpos,fsetpos@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fsetpos,fsetpos@GLIBC_2.2.5");
- int fsetpos64 (FILE *__stream, const fpos64_t *__pos)
+ int _iosys_fsetpos64 (FILE *__stream, const fpos64_t *__pos)
{
TRACE_SYSCALL();
if(!is_filex(__stream)) {
@@ 522,10 526,10 @@ extern "C"
return ret>0?0:ret;
}
}
- __asm__(".symver fsetpos64,fsetpos64@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fsetpos64,fsetpos64@GLIBC_2.2.5");
- long int ftell (FILE *__stream)
+ long int _iosys_ftell (FILE *__stream)
{
long int ret {};
if(is_filex(__stream))
@@ 540,9 544,9 @@ extern "C"
TRACE_SYSCALLN("(%p)=%i",__stream, ret);
return ret;
}
- __asm__(".symver ftell,ftell@GLIBC_2.2.5");
+ __asm__(".symver _iosys_ftell,ftell@GLIBC_2.2.5");
- size_t fwrite (const void *__restrict __ptr, size_t __size,
+ size_t _iosys_fwrite (const void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __s)
{
int ret {};
@@ 569,12 573,13 @@ extern "C"
ret = real_fwrite( __ptr, __size, __n, __s );
}
}
- TRACE_SYSCALLN("(ptr: %p,size: %lu, n: %lu, fil: %p)=%i",__ptr,__size,__n,__s,ret);
+ if (__s != stdout && __s != stderr)
+ TRACE_SYSCALLN("(ptr: %p,size: %lu, n: %lu, fil: %p)=%i",__ptr,__size,__n,__s,ret);
return ret;
}
- __asm__(".symver fwrite,fwrite@GLIBC_2.2.5");
+ __asm__(".symver _iosys_fwrite,fwrite@GLIBC_2.2.5");
- int getc(FILE *__stream)
+ int _iosys_getc(FILE *__stream)
{
int ret {};
if(is_filex(__stream))
@@ 592,9 597,9 @@ extern "C"
TRACE_SYSCALLN("(%p)=%i",__stream, ret);
return ret;
}
- __asm__(".symver getc,getc@GLIBC_2.2.5");
+ __asm__(".symver _iosys_getc,getc@GLIBC_2.2.5");
- int putc(int __c, FILE *__stream)
+ int _iosys_putc(int __c, FILE *__stream)
{
int ret {};
if(is_filex(__stream))
@@ 612,9 617,9 @@ extern "C"
TRACE_SYSCALLN("(%i %p)=%i",__c,__stream, ret);
return ret;
}
- __asm__(".symver putc,putc@GLIBC_2.2.5");
+ __asm__(".symver _iosys_putc,putc@GLIBC_2.2.5");
- int remove (const char *__filename) __THROW
+ int _iosys_remove (const char *__filename) __THROW
{
int ret {};
if(redirect_to_image(__filename))
@@ 631,9 636,9 @@ extern "C"
TRACE_SYSCALLN("(%s)=%i",__filename, ret);
return ret;
}
- __asm__(".symver remove,remove@GLIBC_2.2.5");
+ __asm__(".symver _iosys_remove,remove@GLIBC_2.2.5");
- void rewind (FILE *__stream)
+ void _iosys_rewind (FILE *__stream)
{
TRACE_SYSCALLN("(%p)",__stream);
if(is_filex(__stream))
@@ 647,44 652,44 @@ extern "C"
real_rewind(__stream);
}
}
- __asm__(".symver rewind,rewind@GLIBC_2.2.5");
+ __asm__(".symver _iosys_rewind,rewind@GLIBC_2.2.5");
- void setbuf (FILE *__restrict , char *__restrict ) __THROW
+ void _iosys_setbuf (FILE *__restrict , char *__restrict ) __THROW
{
TRACE_SYSCALL();
- real_fprintf(stderr, "unimplemented call %s\n", __PRETTY_FUNCTION__ );
+ std::cerr << "Unimplemented syscall " << __PRETTY_FUNCTION__ << std::endl;
errno = ENOTSUP;
}
- __asm__(".symver setbuf,setbuf@GLIBC_2.2.5");
+ __asm__(".symver _iosys_setbuf,setbuf@GLIBC_2.2.5");
- int setvbuf (FILE *__restrict __stream, char *__restrict __buf,
+ int _iosys_setvbuf (FILE *__restrict __stream, char *__restrict __buf,
int __modes, size_t __n) __THROW
{
TRACE_SYSCALL();
- real_fprintf(stderr, "unimplemented call %s\n", __PRETTY_FUNCTION__ );
+ std::cerr << "Unimplemented syscall " << __PRETTY_FUNCTION__ << std::endl;
errno = ENOTSUP;
return 0;
}
- __asm__(".symver setvbuf,setbuf@GLIBC_2.2.5");
+ __asm__(".symver _iosys_setvbuf,setbuf@GLIBC_2.2.5");
- void setbuffer (FILE *__restrict __stream, char *__restrict __buf,
+ void _iosys_setbuffer (FILE *__restrict __stream, char *__restrict __buf,
size_t __size) __THROW
{
TRACE_SYSCALL();
- real_fprintf(stderr, "unimplemented call %s\n", __PRETTY_FUNCTION__ );
+ std::cerr << "Unimplemented syscall " << __PRETTY_FUNCTION__ << std::endl;
errno = ENOTSUP;
}
- __asm__(".symver setbuffer,setbuffer@GLIBC_2.2.5");
+ __asm__(".symver _iosys_setbuffer,setbuffer@GLIBC_2.2.5");
/* Make STREAM line-buffered. */
- void setlinebuf (FILE *__stream) __THROW
+ void _iosys_setlinebuf (FILE *__stream) __THROW
{
TRACE_SYSCALL();
errno = ENOTSUP;
- real_fprintf(stderr, "unimplemented call %s\n", __PRETTY_FUNCTION__ );
+ std::cerr << "Unimplemented syscall " << __PRETTY_FUNCTION__ << std::endl;
}
- __asm__(".symver setlinebuf,setlinebuf@GLIBC_2.2.5");
+ __asm__(".symver _iosys_setlinebuf,setlinebuf@GLIBC_2.2.5");
}