Skip to content

Instantly share code, notes, and snippets.

@yangacer
Last active December 19, 2015 17:09
Show Gist options
  • Save yangacer/5989606 to your computer and use it in GitHub Desktop.
Save yangacer/5989606 to your computer and use it in GitHub Desktop.
Glue class member function with fuse API.
#ifndef FUSE_GLUE_FUNCTION_HPP_
#define FUSE_GLUE_FUNCTION_HPP_
#include <functional>
#define DECL_GLUE_FUNC_(CONTEXT_TYPE, FUNCTION_NAME) \
template <typename T> struct glue_with_##FUNCTION_NAME; \
template <typename Ret, typename ...Arg> \
struct glue_with_##FUNCTION_NAME<Ret(*)(Arg...)> \
{ \
static Ret f(Arg... arg) \
{ \
return static_cast<CONTEXT_TYPE*>(fuse_get_context()->private_data)-> \
FUNCTION_NAME(std::forward<Arg>(arg)...); \
} \
};
#define GLUE_2(FROM, TO) &glue_with_##TO<decltype(fuse_operations::FROM)>::f
#define GLUE(NAME) &glue_with_##NAME<decltype(fuse_operations::NAME)>::f
#endif
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include "glue.hpp"
struct hello_fs
{
char const *hello_str;
char const *hello_path;
hello_fs() :
hello_str("Hello World!\n"),
hello_path("/hello")
{}
int getattr(const char *path, struct stat *stbuf)
{
int res = 0;
memset(stbuf, 0, sizeof(struct stat));
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
} else if (strcmp(path, hello_path) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(hello_str);
//stbuf->st_size = 20;
} else
res = -ENOENT;
return res;
}
int readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
(void) offset;
(void) fi;
if (strcmp(path, "/") != 0)
return -ENOENT;
filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);
filler(buf, hello_path + 1, NULL, 0);
return 0;
}
int open(const char *path, struct fuse_file_info *fi)
{
if (strcmp(path, hello_path) != 0)
return -ENOENT;
if ((fi->flags & 3) != O_RDONLY)
return -EACCES;
return 0;
}
int read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
size_t len;
(void) fi;
if(strcmp(path, hello_path) != 0)
return -ENOENT;
len = strlen(hello_str);
//sprintf(gbuf, "addr: %p\n", fuse_get_context()->private_data);
//len = strlen(gbuf);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, hello_str + offset, size);
//memcpy(buf, gbuf + offset, size);
} else
size = 0;
return size;
}
}; // hello_fs
DECL_GLUE_FUNC_(hello_fs, getattr)
DECL_GLUE_FUNC_(hello_fs, readdir)
DECL_GLUE_FUNC_(hello_fs, open)
DECL_GLUE_FUNC_(hello_fs, read)
static struct fuse_operations hello_oper = {
.getattr = GLUE(getattr),
.readdir = GLUE(readdir),
.open = GLUE(open),
.read = GLUE(read),
};
int main(int argc, char *argv[])
{
hello_fs fs;
return fuse_main(argc, argv, &hello_oper, (void*)&fs);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment