libfuse: example/hello.c File Reference

libfuse

hello.c File Reference
`#include <fuse.h>`
`#include <stdio.h>`
`#include <string.h>`
`#include <errno.h>`
`#include <fcntl.h>`
`#include <stddef.h>`
`#include <assert.h>`

Go to the source code of this file.

## Detailed Description

minimal example filesystem using high-level API

Compile with:

    gcc -Wall hello.c `pkg-config fuse3 --cflags --libs` -o hello

## Source code

/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU GPLv2.
See the file GPL2.txt.
*/
#define FUSE_USE_VERSION 31
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <assert.h>
/*
* Command line options
*
* We can't set default values for the char* fields here because
* fuse_opt_parse would attempt to free() them when the user specifies
* different values on the command line.
*/
static struct options {
const char *filename;
const char *contents;
int show_help;
} options;
#define OPTION(t, p) \
{ t, offsetof(struct options, p), 1 }
static const struct fuse_opt option_spec[] = {
OPTION("--name=%s", filename),
OPTION("--contents=%s", contents),
OPTION("-h", show_help),
OPTION("--help", show_help),
FUSE_OPT_END
};
static void *hello_init(struct fuse_conn_info *conn,
struct fuse_config *cfg)
{
(void) conn;
cfg->kernel_cache = 1;
/* Test setting flags the old way */
fuse_set_feature_flag(conn, FUSE_CAP_ASYNC_READ);
fuse_unset_feature_flag(conn, FUSE_CAP_ASYNC_READ);
return NULL;
}
static int hello_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi)
{
(void) fi;
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+1, options.filename) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(options.contents);
} else
res = -ENOENT;
return res;
}
static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi,
enum fuse_readdir_flags flags)
{
(void) offset;
(void) fi;
(void) flags;
if (strcmp(path, "/") != 0)
return -ENOENT;
filler(buf, ".", NULL, 0, FUSE_FILL_DIR_DEFAULTS);
filler(buf, "..", NULL, 0, FUSE_FILL_DIR_DEFAULTS);
filler(buf, options.filename, NULL, 0, FUSE_FILL_DIR_DEFAULTS);
return 0;
}
static int hello_open(const char *path, struct fuse_file_info *fi)
{
if (strcmp(path+1, options.filename) != 0)
return -ENOENT;
if ((fi->flags & O_ACCMODE) != O_RDONLY)
return -EACCES;
return 0;
}
static int hello_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+1, options.filename) != 0)
return -ENOENT;
len = strlen(options.contents);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, options.contents + offset, size);
} else
size = 0;
return size;
}
static const struct fuse_operations hello_oper = {
.init = hello_init,
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};
static void show_help(const char *progname)
{
printf("usage: %s [options] <mountpoint>\n\n", progname);
printf("File-system specific options:\n"
" --name=<s> Name of the \"hello\" file\n"
" (default: \"hello\")\n"
" --contents=<s> Contents \"hello\" file\n"
" (default \"Hello, World!\\n\")\n"
"\n");
}
int main(int argc, char *argv[])
{
int ret;
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
/* Set defaults -- we have to use strdup so that
fuse_opt_parse can free the defaults if other
values are specified */
options.filename = strdup("hello");
options.contents = strdup("Hello World!\n");
/* Parse options */
if (fuse_opt_parse(&args, &options, option_spec, NULL) == -1)
return 1;
/* When --help is specified, first print our own file-system
specific help text, then signal fuse_main to show
additional help (by adding `--help` to the options again)
without usage: line (by setting argv[0] to the empty
string) */
if (options.show_help) {
show_help(argv[0]);
assert(fuse_opt_add_arg(&args, "--help") == 0);
args.argv[0][0] = '\0';
}
ret = fuse_main(args.argc, args.argv, &hello_oper, NULL);
fuse_opt_free_args(&args);
return ret;
}
fuse_fill_dir_t
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
Definition fuse.h:87
FUSE_FILL_DIR_DEFAULTS
@ FUSE_FILL_DIR_DEFAULTS
Definition fuse.h:68
fuse_readdir_flags
fuse_readdir_flags
Definition fuse.h:42
fuse_unset_feature_flag
void fuse_unset_feature_flag(struct fuse_conn_info *conn, uint64_t flag)
Definition fuse_lowlevel.c:2050
fuse_set_feature_flag
bool fuse_set_feature_flag(struct fuse_conn_info *conn, uint64_t flag)
Definition fuse_lowlevel.c:2035
FUSE_CAP_ASYNC_READ
#define FUSE_CAP_ASYNC_READ
Definition fuse_common.h:177
fuse_opt_add_arg
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition fuse_opt.c:55
fuse_opt_free_args
void fuse_opt_free_args(struct fuse_args *args)
Definition fuse_opt.c:34
fuse_opt_parse
int fuse_opt_parse(struct fuse_args *args, void *data, const struct fuse_opt opts[], fuse_opt_proc_t proc)
Definition fuse_opt.c:398
FUSE_ARGS_INIT
#define FUSE_ARGS_INIT(argc, argv)
Definition fuse_opt.h:123
FUSE_OPT_END
#define FUSE_OPT_END
Definition fuse_opt.h:104
fuse_args
Definition fuse_opt.h:109
fuse_args::argc
int argc
Definition fuse_opt.h:111
fuse_args::argv
char ** argv
Definition fuse_opt.h:114
fuse_config
Definition fuse.h:101
fuse_config::kernel_cache
int32_t kernel_cache
Definition fuse.h:245
fuse_conn_info
Definition fuse_common.h:538
fuse_file_info
Definition fuse_common.h:50
fuse_file_info::flags
int32_t flags
Definition fuse_common.h:52
fuse_operations
Definition fuse.h:349
fuse_operations::init
void *(* init)(struct fuse_conn_info *conn, struct fuse_config *cfg)
Definition fuse.h:641
fuse_opt
Definition fuse_opt.h:77
fuse_opt::offset
unsigned long offset
Definition fuse_opt.h:85

Definition in file hello.c.