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 GPL.
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 return NULL;
61 }
62
63 static int hello_getattr(const char *path, struct stat *stbuf,
64 struct fuse_file_info *fi)
65 {
66 (void) fi;
67 int res = 0;
68
69 memset(stbuf, 0, sizeof(struct stat));
70 if (strcmp(path, "/") == 0) {
71 stbuf->st_mode = S_IFDIR | 0755;
72 stbuf->st_nlink = 2;
73 } else if (strcmp(path+1, options.filename) == 0) {
74 stbuf->st_mode = S_IFREG | 0444;
75 stbuf->st_nlink = 1;
76 stbuf->st_size = strlen(options.contents);
77 } else
78 res = -ENOENT;
79
80 return res;
81 }
82
83 static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
84 off_t offset, struct fuse_file_info *fi,
85 enum fuse_readdir_flags flags)
86 {
87 (void) offset;
88 (void) fi;
89 (void) flags;
90
91 if (strcmp(path, "/") != 0)
92 return -ENOENT;
93
94 filler(buf, ".", NULL, 0, 0);
95 filler(buf, "..", NULL, 0, 0);
96 filler(buf, options.filename, NULL, 0, 0);
97
98 return 0;
99 }
100
101 static int hello_open(const char *path, struct fuse_file_info *fi)
102 {
103 if (strcmp(path+1, options.filename) != 0)
104 return -ENOENT;
105
106 if ((fi->flags & O_ACCMODE) != O_RDONLY)
107 return -EACCES;
108
109 return 0;
110 }
111
112 static int hello_read(const char *path, char *buf, size_t size, off_t offset,
113 struct fuse_file_info *fi)
114 {
115 size_t len;
116 (void) fi;
117 if(strcmp(path+1, options.filename) != 0)
118 return -ENOENT;
119
120 len = strlen(options.contents);
121 if (offset < len) {
122 if (offset + size > len)
123 size = len - offset;
124 memcpy(buf, options.contents + offset, size);
125 } else
126 size = 0;
127
128 return size;
129 }
130
131 static struct fuse_operations hello_oper = {
132 .init = hello_init,
133 .getattr = hello_getattr,
134 .readdir = hello_readdir,
135 .open = hello_open,
136 .read = hello_read,
137 };
138
139 static void show_help(const char *progname)
140 {
141 printf("usage: %s [options] <mountpoint>\n\n", progname);
142 printf("File-system specific options:\n"
143 " --name=<s> Name of the \"hello\" file\n"
144 " (default: \"hello\")\n"
145 " --contents=<s> Contents \"hello\" file\n"
146 " (default \"Hello, World!\\n\")\n"
147 "\n");
148 }
149
150 int main(int argc, char *argv[])
151 {
152 int ret;
153 struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
154
155 /* Set defaults -- we have to use strdup so that
156 fuse_opt_parse can free the defaults if other
157 values are specified */
158 options.filename = strdup("hello");
159 options.contents = strdup("Hello World!\n");
160
161 /* Parse options */
162 if (fuse_opt_parse(&args, &options, option_spec, NULL) == -1)
163 return 1;
164
165 /* When --help is specified, first print our own file-system
166 specific help text, then signal fuse_main to show
167 additional help (by adding `--help` to the options again)
168 without usage: line (by setting argv[0] to the empty
169 string) */
170 if (options.show_help) {
171 show_help(argv[0]);
172 assert(fuse_opt_add_arg(&args, "--help") == 0);
173 args.argv[0][0] = '\0';
174 }
175
176 ret = fuse_main(args.argc, args.argv, &hello_oper, NULL);
177 fuse_opt_free_args(&args);
178 return ret;
179 }
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_conn_info
Definition: fuse_common.h:385
fuse_args::argc
int argc
Definition: fuse_opt.h:111
fuse_operations::init
void *(* init)(struct fuse_conn_info *conn, struct fuse_config *cfg)
Definition: fuse.h:578
fuse_opt::offset
unsigned long offset
Definition: fuse_opt.h:85
FUSE_ARGS_INIT
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
fuse_file_info
Definition: fuse_common.h:44
fuse_operations
Definition: fuse.h:299
fuse_file_info::flags
int flags
Definition: fuse_common.h:46
fuse_args::argv
char ** argv
Definition: fuse_opt.h:114
FUSE_OPT_END
#define FUSE_OPT_END
Definition: fuse_opt.h:104
fuse_opt_free_args
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:34
fuse_main
#define fuse_main(argc, argv, op, private_data)
Definition: fuse.h:869
fuse_readdir_flags
fuse_readdir_flags
Definition: fuse.h:42
fuse_config
Definition: fuse.h:93
fuse_opt
Definition: fuse_opt.h:77
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:82
fuse_args
Definition: fuse_opt.h:109
fuse_opt_add_arg
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:55
fuse_config::kernel_cache
int kernel_cache
Definition: fuse.h:237