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 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, FUSE_FILL_DIR_DEFAULTS);
95 filler(buf, "..", NULL, 0, FUSE_FILL_DIR_DEFAULTS);
96 filler(buf, options.filename, NULL, 0, FUSE_FILL_DIR_DEFAULTS);
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 const 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.h
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_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_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