diff options
Diffstat (limited to 'libfusepp/fuseapp.h')
-rw-r--r-- | libfusepp/fuseapp.h | 104 |
1 files changed, 100 insertions, 4 deletions
diff --git a/libfusepp/fuseapp.h b/libfusepp/fuseapp.h index 1c94f13..bb18c02 100644 --- a/libfusepp/fuseapp.h +++ b/libfusepp/fuseapp.h @@ -3,7 +3,10 @@ #define FUSE_USE_VERSION 26 #include <fuse.h> +#include <typeinfo> #include <exception> +#include <stdio.h> +#include <errno.h> class FuseAppBase { public: @@ -47,12 +50,105 @@ class FuseAppBase { virtual int bmap(const char *, size_t blocksize, uint64_t *idx); virtual int ioctl(const char *, int cmd, void *arg, struct fuse_file_info *, unsigned int flags, void * data); virtual int poll(const char *, struct fuse_file_info *, struct fuse_pollhandle *, unsigned *); - virtual int write_buf (const char *, struct fuse_bufvec *buf, off_t off, struct fuse_file_info *); - virtual int read_buf (const char *, struct fuse_bufvec **bufp, size_t size, off_t off, struct fuse_file_info *); - virtual int flock (const char *, struct fuse_file_info *, int op); + virtual int write_buf(const char *, struct fuse_bufvec *buf, off_t off, struct fuse_file_info *); + virtual int read_buf(const char *, struct fuse_bufvec **bufp, size_t size, off_t off, struct fuse_file_info *); + virtual int flock(const char *, struct fuse_file_info *, int op); + virtual int fallocate(const char *, int, off_t, off_t, struct fuse_file_info *); virtual int onError(const std::exception & err) throw(); - static int run(int &, char ** &, FuseAppBase *); +#define IFIMPL(func) typeid(&FuseAppBase::func) == typeid(&FuseApp::func) ? NULL : + template <typename FuseApp> + static int run(int & argc, char** & argv, FuseApp * fa) + { + auto args = runint(argc, argv, fa); + struct fuse_operations operations = { + IFIMPL(getattr) fuseCall<const char *, struct stat *>::helper<&FuseAppBase::getattr>, + IFIMPL(readlink) fuseCall<const char *, char *, size_t>::helper<&FuseAppBase::readlink>, + NULL, // getdir deprecated + IFIMPL(mknod) fuseCall<const char *, mode_t, dev_t>::helper<&FuseAppBase::mknod>, + IFIMPL(mkdir) fuseCall<const char *, mode_t>::helper<&FuseAppBase::mkdir>, + IFIMPL(unlink) fuseCall<const char *>::helper<&FuseAppBase::unlink>, + IFIMPL(rmdir) fuseCall<const char *>::helper<&FuseAppBase::rmdir>, + IFIMPL(symlink) fuseCall<const char *, const char *>::helper<&FuseAppBase::symlink>, + IFIMPL(rename) fuseCall<const char *, const char *>::helper<&FuseAppBase::rename>, + IFIMPL(link) fuseCall<const char *, const char *>::helper<&FuseAppBase::link>, + IFIMPL(chmod) fuseCall<const char *, mode_t>::helper<&FuseAppBase::chmod>, + IFIMPL(chown) fuseCall<const char *, uid_t, gid_t>::helper<&FuseAppBase::chown>, + IFIMPL(truncate) fuseCall<const char *, off_t>::helper<&FuseAppBase::truncate>, + NULL, // utime deprecated + IFIMPL(open) fuseCall<const char *, struct fuse_file_info *>::helper<&FuseAppBase::open>, + IFIMPL(read) fuseCall<const char *, char *, size_t, off_t, struct fuse_file_info *>::helper<&FuseAppBase::read>, + IFIMPL(write) fuseCall<const char *, const char *, size_t, off_t, struct fuse_file_info *>::helper<&FuseAppBase::write>, + IFIMPL(statfs) fuseCall<const char *, struct statvfs *>::helper<&FuseAppBase::statfs>, + IFIMPL(flush) fuseCall<const char *, struct fuse_file_info *>::helper<&FuseAppBase::flush>, + IFIMPL(release) fuseCall<const char *, struct fuse_file_info *>::helper<&FuseAppBase::release>, + IFIMPL(fsync) fuseCall<const char *, int, struct fuse_file_info *>::helper<&FuseAppBase::fsync>, + IFIMPL(setxattr) fuseCall<const char *, const char *, const char *, size_t, int>::helper<&FuseAppBase::setxattr>, + IFIMPL(getxattr) fuseCall<const char *, const char *, char *, size_t>::helper<&FuseAppBase::getxattr>, + IFIMPL(listxattr) fuseCall<const char *, char *, size_t>::helper<&FuseAppBase::listxattr>, + IFIMPL(removexattr) fuseCall<const char *, const char *>::helper<&FuseAppBase::removexattr>, + IFIMPL(opendir) fuseCall<const char *, struct fuse_file_info *>::helper<&FuseAppBase::opendir>, + IFIMPL(readdir) fuseCall<const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *>::helper<&FuseAppBase::readdir>, + IFIMPL(releasedir) fuseCall<const char *, struct fuse_file_info *>::helper<&FuseAppBase::releasedir>, + IFIMPL(fsyncdir) fuseCall<const char *, int, struct fuse_file_info *>::helper<&FuseAppBase::fsyncdir>, + fuseInit, + fuseDestroy, + IFIMPL(access) fuseCall<const char *, int>::helper<&FuseAppBase::access>, + IFIMPL(create) fuseCall<const char *, mode_t, struct fuse_file_info *>::helper<&FuseAppBase::create>, + IFIMPL(fgetattr) fuseCall<const char *, off_t, struct fuse_file_info *>::helper<&FuseAppBase::ftruncate>, + IFIMPL(fgetattr) fuseCall<const char *, struct stat *, struct fuse_file_info *>::helper<&FuseAppBase::fgetattr>, +#if (FUSE_MINOR_VERSION >= 6) + IFIMPL(lock) fuseCall<const char *, struct fuse_file_info *, int, struct flock *>::helper<&FuseAppBase::lock>, + IFIMPL(utimens) fuseCall<const char *, const struct timespec [2]>::helper<&FuseAppBase::utimens>, + IFIMPL(bmap) 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 + IFIMPL(ioctl) fuseCall<const char *, int, void *, struct fuse_file_info *, unsigned int, void *>::helper<&FuseAppBase::ioctl>, + IFIMPL(poll) fuseCall<const char *, struct fuse_file_info *, struct fuse_pollhandle *, unsigned *>::helper<&FuseAppBase::poll>, +#if (FUSE_MINOR_VERSION >= 9) + IFIMPL(write_buf) fuseCall<const char *, struct fuse_bufvec *, off_t, struct fuse_file_info *>::helper<&FuseAppBase::write_buf>, + IFIMPL(read_buf) fuseCall<const char *, struct fuse_bufvec **, size_t, off_t, struct fuse_file_info *>::helper<&FuseAppBase::read_buf>, + IFIMPL(flock) fuseCall<const char *, struct fuse_file_info *, int>::helper<&FuseAppBase::flock>, + IFIMPL(fallocate) fuseCall<const char *, int, off_t, off_t, struct fuse_file_info *>::helper<&FuseAppBase::fallocate>, +#endif +#endif +#endif + }; + return fuse_main(args.argc, args.argv, &operations, fa); + } + private: + static struct fuse_args runint(int &, char ** &, FuseAppBase *); + static void * fuseInit(struct fuse_conn_info *conn); + static void fuseDestroy(void *); + + 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 FuseAppBase * fuseApp; }; #endif |