diff options
Diffstat (limited to 'libfusepp/fuseapp.cpp')
-rw-r--r-- | libfusepp/fuseapp.cpp | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/libfusepp/fuseapp.cpp b/libfusepp/fuseapp.cpp new file mode 100644 index 0000000..e81a116 --- /dev/null +++ b/libfusepp/fuseapp.cpp @@ -0,0 +1,271 @@ +#include "fuseapp.h" +#include <errno.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <typeinfo> + +static FuseAppBase * fuseApp; + +FuseAppBase::FuseAppBase() +{ +} +FuseAppBase::~FuseAppBase() +{ +} +void * FuseAppBase::init(fuse_conn_info*) +{ + return NULL; +} +int FuseAppBase::opt_parse(void*, const char *, int, fuse_args*) +{ + return 1; +} +int FuseAppBase::access(const char *, int) +{ + return -ENOSYS; +} +int FuseAppBase::chmod(const char *, mode_t) +{ + return -ENOSYS; +} +int FuseAppBase::chown(const char *, uid_t, gid_t) +{ + return -ENOSYS; +} +int FuseAppBase::create(const char *, mode_t, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::fgetattr(const char *, struct stat *, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::flush(const char *, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::fsync(const char *, int, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::fsyncdir(const char *, int, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::ftruncate(const char *, off_t, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::getattr(const char *, struct stat *) +{ + return -ENOSYS; +} +int FuseAppBase::getxattr(const char *, const char *, char *, size_t) +{ + return -ENOSYS; +} +int FuseAppBase::link(const char *, const char *) +{ + return -ENOSYS; +} +int FuseAppBase::listxattr(const char *, char *, size_t) +{ + return -ENOSYS; +} +int FuseAppBase::mkdir(const char *, mode_t) +{ + return -ENOSYS; +} +int FuseAppBase::mknod(const char *, mode_t, dev_t) +{ + return -ENOSYS; +} +int FuseAppBase::open(const char *, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::opendir(const char *, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::read(const char *, char *, size_t, off_t, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::readlink(const char *, char *, size_t) +{ + return -ENOSYS; +} +int FuseAppBase::release(const char *, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::releasedir(const char *, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::removexattr(const char *, const char *) +{ + return -ENOSYS; +} +int FuseAppBase::rename(const char *, const char *) +{ + return -ENOSYS; +} +int FuseAppBase::rmdir(const char *) +{ + return -ENOSYS; +} +int FuseAppBase::setxattr(const char *, const char *, const char *, size_t, int) +{ + return -ENOSYS; +} +int FuseAppBase::statfs(const char *, struct statvfs *) +{ + return -ENOSYS; +} +int FuseAppBase::symlink(const char *, const char *) +{ + return -ENOSYS; +} +int FuseAppBase::truncate(const char *, off_t) +{ + return -ENOSYS; +} +int FuseAppBase::unlink(const char *) +{ + return -ENOSYS; +} +int FuseAppBase::write(const char *, const char *, size_t, off_t, struct fuse_file_info *) +{ + return -ENOSYS; +} +int FuseAppBase::lock(const char *, struct fuse_file_info *, int, struct flock *) +{ + return -ENOSYS; +} +int FuseAppBase::utimens(const char *, const struct timespec[2]) +{ + return -ENOSYS; +} +int FuseAppBase::bmap(const char *, size_t, uint64_t *) +{ + return -ENOSYS; +} +int FuseAppBase::onError(const std::exception & e) throw() +{ + fprintf(stderr, "Unknown exception calling (what: %s)\n", e.what()); + return -ENOSYS; +} + +template <typename... Args> +class fuseCall { + public: + template <int (FuseAppBase::*f)(Args...)> + static int helper(Args ... a) + { + try { + return (fuseApp->*f)(a...); + } + catch (const std::exception & ex) { + if (int rtn = fuseApp->onError(ex)) { + return rtn; + } + return helper<f>(a...); + } + catch (...) { + fprintf(stderr, "Unknown exception calling %s\n", typeid(f).name()); + return -ENOSYS; + } + } +}; +static void * fuseInit (struct fuse_conn_info *conn) +{ + return fuseApp->init(conn); +} +static void fuseDestroy(void *) +{ + delete fuseApp; +} + +int +FuseAppBase::run(int & argc, char** & argv, FuseAppBase * fa) +{ + struct fuse_opt fuse_opts[] = { + { NULL, 0, 0 } + }; + fuseApp = fa; + struct fuse_operations operations = { + fuseCall<const char *, struct stat *>::helper<&FuseAppBase::getattr>, + fuseCall<const char *, char *, size_t>::helper<&FuseAppBase::readlink>, + NULL, // getdir deprecated + fuseCall<const char *, mode_t, dev_t>::helper<&FuseAppBase::mknod>, + fuseCall<const char *, mode_t>::helper<&FuseAppBase::mkdir>, + fuseCall<const char *>::helper<&FuseAppBase::unlink>, + fuseCall<const char *>::helper<&FuseAppBase::rmdir>, + fuseCall<const char *, const char *>::helper<&FuseAppBase::symlink>, + fuseCall<const char *, const char *>::helper<&FuseAppBase::rename>, + fuseCall<const char *, const char *>::helper<&FuseAppBase::link>, + fuseCall<const char *, mode_t>::helper<&FuseAppBase::chmod>, + fuseCall<const char *, uid_t, gid_t>::helper<&FuseAppBase::chown>, + fuseCall<const char *, off_t>::helper<&FuseAppBase::truncate>, + NULL, // utime deprecated + fuseCall<const char *, struct fuse_file_info *>::helper<&FuseAppBase::open>, + fuseCall<const char *, char *, size_t, off_t, struct fuse_file_info *>::helper<&FuseAppBase::read>, + fuseCall<const char *, const char *, size_t, off_t, struct fuse_file_info *>::helper<&FuseAppBase::write>, + fuseCall<const char *, struct statvfs *>::helper<&FuseAppBase::statfs>, + fuseCall<const char *, struct fuse_file_info *>::helper<&FuseAppBase::flush>, + fuseCall<const char *, struct fuse_file_info *>::helper<&FuseAppBase::release>, + fuseCall<const char *, int, struct fuse_file_info *>::helper<&FuseAppBase::fsync>, + fuseCall<const char *, const char *, const char *, size_t, int>::helper<&FuseAppBase::setxattr>, + fuseCall<const char *, const char *, char *, size_t>::helper<&FuseAppBase::getxattr>, + fuseCall<const char *, char *, size_t>::helper<&FuseAppBase::listxattr>, + fuseCall<const char *, const char *>::helper<&FuseAppBase::removexattr>, + fuseCall<const char *, struct fuse_file_info *>::helper<&FuseAppBase::opendir>, + fuseCall<const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *>::helper<&FuseAppBase::readdir>, + fuseCall<const char *, struct fuse_file_info *>::helper<&FuseAppBase::releasedir>, + fuseCall<const char *, int, struct fuse_file_info *>::helper<&FuseAppBase::fsyncdir>, + fuseInit, + fuseDestroy, + fuseCall<const char *, int>::helper<&FuseAppBase::access>, + fuseCall<const char *, mode_t, struct fuse_file_info *>::helper<&FuseAppBase::create>, + fuseCall<const char *, off_t, struct fuse_file_info *>::helper<&FuseAppBase::ftruncate>, + fuseCall<const char *, struct stat *, struct fuse_file_info *>::helper<&FuseAppBase::fgetattr> +#if (FUSE_MINOR_VERSION >= 6) + , + fuseCall<const char *, struct fuse_file_info *, int, struct flock *>::helper<&FuseAppBase::lock>, + fuseCall<const char *, const struct timespec [2]>::helper<&FuseAppBase::utimens>, + fuseCall<const char *, size_t, uint64_t *>::helper<&FuseAppBase::bmap> +#if (FUSE_MINOR_VERSION >= 8) + , + 0, // flag_nullpath_ok +#if (FUSE_MINOR_VERSION >= 9) + 0, // flag_nopath + 0, // flag_utime_omit_ok +#endif + 0, // flag_reserved + NULL, // ioctl + NULL // poll +#if (FUSE_MINOR_VERSION >= 9) + , + NULL, // writebuf + NULL, // readbuf + NULL // flock +#endif +#endif +#endif + }; + struct fuse_args args = FUSE_ARGS_INIT(argc, argv); + if (fuse_opt_parse(&args, fuseApp, fuse_opts, + fuseCall<void *, const char *, int, struct fuse_args *>::helper<&FuseAppBase::opt_parse>) == -1) { + exit(1); + } + return fuse_main(args.argc, args.argv, &operations, fa); +} + |