libfuse

hello.c
Go to the documentation of this file.
1/*
2 FUSE: Filesystem in Userspace
3 Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
4
5 This program can be distributed under the terms of the GNU GPLv2.
6 See the file COPYING.
7*/
8
22#define FUSE_USE_VERSION 31
23
24#include <fuse.h>
25#include <stdio.h>
26#include <string.h>
27#include <errno.h>
28#include <fcntl.h>
29#include <stddef.h>
30#include <assert.h>
31
32/*
33 * Command line options
34 *
35 * We can't set default values for the char* fields here because
36 * fuse_opt_parse would attempt to free() them when the user specifies
37 * different values on the command line.
38 */
39 static struct options {
40 const char *filename;
41 const char *contents;
42 int show_help;
43} options;
44
45#define OPTION(t, p) \
46 { t, offsetof(struct options, p), 1 }
47 static const struct fuse_opt option_spec[] = {
48 OPTION("--name=%s", filename),
49 OPTION("--contents=%s", contents),
50 OPTION("-h", show_help),
51 OPTION("--help", show_help),
52 FUSE_OPT_END
53};
54
55 static void *hello_init(struct fuse_conn_info *conn,
56 struct fuse_config *cfg)
57{
58 (void) conn;
59 cfg->kernel_cache = 1;
60
61 /* Test setting flags the old way */
62 conn->want = FUSE_CAP_ASYNC_READ;
63 conn->want &= ~FUSE_CAP_ASYNC_READ;
64
65 return NULL;
66}
67
68 static int hello_getattr(const char *path, struct stat *stbuf,
69 struct fuse_file_info *fi)
70{
71 (void) fi;
72 int res = 0;
73
74 memset(stbuf, 0, sizeof(struct stat));
75 if (strcmp(path, "/") == 0) {
76 stbuf->st_mode = S_IFDIR | 0755;
77 stbuf->st_nlink = 2;
78 } else if (strcmp(path+1, options.filename) == 0) {
79 stbuf->st_mode = S_IFREG | 0444;
80 stbuf->st_nlink = 1;
81 stbuf->st_size = strlen(options.contents);
82 } else
83 res = -ENOENT;
84
85 return res;
86}
87
88 static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
89 off_t offset, struct fuse_file_info *fi,
90 enum fuse_readdir_flags flags)
91{
92 (void) offset;
93 (void) fi;
94 (void) flags;
95
96 if (strcmp(path, "/") != 0)
97 return -ENOENT;
98
99 filler(buf, ".", NULL, 0, FUSE_FILL_DIR_DEFAULTS);
100 filler(buf, "..", NULL, 0, FUSE_FILL_DIR_DEFAULTS);
101 filler(buf, options.filename, NULL, 0, FUSE_FILL_DIR_DEFAULTS);
102
103 return 0;
104}
105
106 static int hello_open(const char *path, struct fuse_file_info *fi)
107{
108 if (strcmp(path+1, options.filename) != 0)
109 return -ENOENT;
110
111 if ((fi->flags & O_ACCMODE) != O_RDONLY)
112 return -EACCES;
113
114 return 0;
115}
116
117 static int hello_read(const char *path, char *buf, size_t size, off_t offset,
118 struct fuse_file_info *fi)
119{
120 size_t len;
121 (void) fi;
122 if(strcmp(path+1, options.filename) != 0)
123 return -ENOENT;
124
125 len = strlen(options.contents);
126 if (offset < len) {
127 if (offset + size > len)
128 size = len - offset;
129 memcpy(buf, options.contents + offset, size);
130 } else
131 size = 0;
132
133 return size;
134}
135
136 static const struct fuse_operations hello_oper = {
137 .init = hello_init,
138 .getattr = hello_getattr,
139 .readdir = hello_readdir,
140 .open = hello_open,
141 .read = hello_read,
142};
143
144 static void show_help(const char *progname)
145{
146 printf("usage: %s [options] <mountpoint>\n\n", progname);
147 printf("File-system specific options:\n"
148 " --name=<s> Name of the \"hello\" file\n"
149 " (default: \"hello\")\n"
150 " --contents=<s> Contents \"hello\" file\n"
151 " (default \"Hello, World!\\n\")\n"
152 "\n");
153}
154
155 int main(int argc, char *argv[])
156{
157 int ret;
158 struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
159
160 /* Set defaults -- we have to use strdup so that
161 fuse_opt_parse can free the defaults if other
162 values are specified */
163 options.filename = strdup("hello");
164 options.contents = strdup("Hello World!\n");
165
166 /* Parse options */
167 if (fuse_opt_parse(&args, &options, option_spec, NULL) == -1)
168 return 1;
169
170 /* When --help is specified, first print our own file-system
171 specific help text, then signal fuse_main to show
172 additional help (by adding `--help` to the options again)
173 without usage: line (by setting argv[0] to the empty
174 string) */
175 if (options.show_help) {
176 show_help(argv[0]);
177 assert(fuse_opt_add_arg(&args, "--help") == 0);
178 args.argv[0][0] = '\0';
179 }
180
181 ret = fuse_main(args.argc, args.argv, &hello_oper, NULL);
182 fuse_opt_free_args(&args);
183 return ret;
184}
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_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_CAP_ASYNC_READ
#define FUSE_CAP_ASYNC_READ
Definition fuse_common.h:187
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:555
fuse_conn_info::want
uint32_t want
Definition fuse_common.h:607
fuse_file_info
Definition fuse_common.h:58
fuse_file_info::flags
int32_t flags
Definition fuse_common.h:60
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