summaryrefslogtreecommitdiff
path: root/libfusepp/fuseAppBase.h
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2015-02-15 16:13:47 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2015-05-06 00:40:49 +0100
commitf46bafac28550d6b0c1ef61d8e3c15d26b40b298 (patch)
tree3e26ea7fe97ce52d02323f82309cd8a06eb4ba24 /libfusepp/fuseAppBase.h
parentCentralize slicer lib defs (diff)
downloadnetfs-f46bafac28550d6b0c1ef61d8e3c15d26b40b298.tar.bz2
netfs-f46bafac28550d6b0c1ef61d8e3c15d26b40b298.tar.xz
netfs-f46bafac28550d6b0c1ef61d8e3c15d26b40b298.zip
Refactor to make more testable
Diffstat (limited to 'libfusepp/fuseAppBase.h')
-rw-r--r--libfusepp/fuseAppBase.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/libfusepp/fuseAppBase.h b/libfusepp/fuseAppBase.h
new file mode 100644
index 0000000..a320d36
--- /dev/null
+++ b/libfusepp/fuseAppBase.h
@@ -0,0 +1,162 @@
+#ifndef FUSEAPP_H
+#define FUSEAPP_H
+
+#define FUSE_USE_VERSION 26
+#include <fuse.h>
+#include <typeinfo>
+#include <exception>
+#include <stdio.h>
+#include <errno.h>
+
+class FuseAppBase {
+ public:
+ FuseAppBase();
+ virtual ~FuseAppBase() = 0;
+ virtual void * init (struct fuse_conn_info * info);
+ virtual int opt_parse(void *, const char * arg, int key, struct fuse_args *);
+ virtual int access(const char *, int);
+ virtual int chmod(const char *, mode_t);
+ virtual int chown(const char *, uid_t, gid_t);
+ virtual int create(const char *, mode_t, struct fuse_file_info *);
+ virtual int fgetattr(const char *, struct stat *, struct fuse_file_info *);
+ virtual int flush(const char *, struct fuse_file_info *);
+ virtual int fsync(const char *, int, struct fuse_file_info *);
+ virtual int fsyncdir(const char *, int, struct fuse_file_info *);
+ virtual int ftruncate(const char *, off_t, struct fuse_file_info *);
+ virtual int getattr(const char *, struct stat *);
+ virtual int getxattr(const char *, const char *, char *, size_t);
+ virtual int link(const char *, const char *);
+ virtual int listxattr(const char *, char *, size_t);
+ virtual int mkdir(const char *, mode_t);
+ virtual int mknod(const char *, mode_t, dev_t);
+ virtual int open(const char *, struct fuse_file_info *);
+ virtual int opendir(const char *, struct fuse_file_info *);
+ virtual int read(const char *, char *, size_t, off_t, struct fuse_file_info *);
+ virtual int readdir(const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *);
+ virtual int readlink(const char *, char *, size_t);
+ virtual int release(const char *, struct fuse_file_info *);
+ virtual int releasedir(const char *, struct fuse_file_info *);
+ virtual int removexattr(const char *, const char *);
+ virtual int rename(const char *, const char *);
+ virtual int rmdir(const char *);
+ virtual int setxattr(const char *, const char *, const char *, size_t, int);
+ virtual int statfs(const char *, struct statvfs *);
+ virtual int symlink(const char *, const char *);
+ virtual int truncate(const char *, off_t);
+ virtual int unlink(const char *);
+ virtual int write(const char *, const char *, size_t, off_t, struct fuse_file_info *);
+ virtual int lock(const char *, struct fuse_file_info *, int cmd, struct flock *);
+ virtual int utimens(const char *, const struct timespec tv[2]);
+ 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 fallocate(const char *, int, off_t, off_t, struct fuse_file_info *);
+ virtual int onError(const std::exception & err) throw();
+
+#define GetHelper(func) getHelper<&FuseAppBase::func>(typeid(&FuseAppBase::func) != typeid(&FuseApp::func))
+ template <typename FuseApp>
+ static int run(int & argc, char** & argv, FuseApp * fa)
+ {
+ auto args = runint(argc, argv, fa);
+ struct fuse_operations operations = {
+ fuseCall<const char *, struct stat *>::GetHelper(getattr),
+ fuseCall<const char *, char *, size_t>::GetHelper(readlink),
+ NULL, // getdir deprecated
+ fuseCall<const char *, mode_t, dev_t>::GetHelper(mknod),
+ fuseCall<const char *, mode_t>::GetHelper(mkdir),
+ fuseCall<const char *>::GetHelper(unlink),
+ fuseCall<const char *>::GetHelper(rmdir),
+ fuseCall<const char *, const char *>::GetHelper(symlink),
+ fuseCall<const char *, const char *>::GetHelper(rename),
+ fuseCall<const char *, const char *>::GetHelper(link),
+ fuseCall<const char *, mode_t>::GetHelper(chmod),
+ fuseCall<const char *, uid_t, gid_t>::GetHelper(chown),
+ fuseCall<const char *, off_t>::GetHelper(truncate),
+ NULL, // utime deprecated
+ fuseCall<const char *, struct fuse_file_info *>::GetHelper(open),
+ fuseCall<const char *, char *, size_t, off_t, struct fuse_file_info *>::GetHelper(read),
+ fuseCall<const char *, const char *, size_t, off_t, struct fuse_file_info *>::GetHelper(write),
+ fuseCall<const char *, struct statvfs *>::GetHelper(statfs),
+ fuseCall<const char *, struct fuse_file_info *>::GetHelper(flush),
+ fuseCall<const char *, struct fuse_file_info *>::GetHelper(release),
+ fuseCall<const char *, int, struct fuse_file_info *>::GetHelper(fsync),
+ fuseCall<const char *, const char *, const char *, size_t, int>::GetHelper(setxattr),
+ fuseCall<const char *, const char *, char *, size_t>::GetHelper(getxattr),
+ fuseCall<const char *, char *, size_t>::GetHelper(listxattr),
+ fuseCall<const char *, const char *>::GetHelper(removexattr),
+ fuseCall<const char *, struct fuse_file_info *>::GetHelper(opendir),
+ fuseCall<const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *>::GetHelper(readdir),
+ fuseCall<const char *, struct fuse_file_info *>::GetHelper(releasedir),
+ fuseCall<const char *, int, struct fuse_file_info *>::GetHelper(fsyncdir),
+ fuseInit,
+ fuseDestroy,
+ fuseCall<const char *, int>::GetHelper(access),
+ fuseCall<const char *, mode_t, struct fuse_file_info *>::GetHelper(create),
+ fuseCall<const char *, off_t, struct fuse_file_info *>::GetHelper(ftruncate),
+ fuseCall<const char *, struct stat *, struct fuse_file_info *>::GetHelper(fgetattr),
+#if (FUSE_MINOR_VERSION >= 6)
+ fuseCall<const char *, struct fuse_file_info *, int, struct flock *>::GetHelper(lock),
+ fuseCall<const char *, const struct timespec [2]>::GetHelper(utimens),
+ fuseCall<const char *, size_t, uint64_t *>::GetHelper(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
+ fuseCall<const char *, int, void *, struct fuse_file_info *, unsigned int, void *>::GetHelper(ioctl),
+ fuseCall<const char *, struct fuse_file_info *, struct fuse_pollhandle *, unsigned *>::GetHelper(poll),
+#if (FUSE_MINOR_VERSION >= 9)
+ fuseCall<const char *, struct fuse_bufvec *, off_t, struct fuse_file_info *>::GetHelper(write_buf),
+ fuseCall<const char *, struct fuse_bufvec **, size_t, off_t, struct fuse_file_info *>::GetHelper(read_buf),
+ fuseCall<const char *, struct fuse_file_info *, int>::GetHelper(flock),
+ fuseCall<const char *, int, off_t, off_t, struct fuse_file_info *>::GetHelper(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:
+ typedef int (*WrapperFunc)(Args...);
+ template <int (FuseAppBase::*b)(Args...)>
+ static WrapperFunc getHelper(bool implemented)
+ {
+ auto func = &helper<b>;
+ return implemented ? func : NULL;
+ }
+ 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
+