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 */
39static 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 }
47static 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),
53};
54
55static 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
63static 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
83static 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
101static 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
112static 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
131static 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
139static 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
150int 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}
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:85
#define fuse_main(argc, argv, op, private_data)
Definition: fuse.h:913
fuse_readdir_flags
Definition: fuse.h:42
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
Definition: fuse_opt.c:55
void fuse_opt_free_args(struct fuse_args *args)
Definition: fuse_opt.c:34
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
#define FUSE_ARGS_INIT(argc, argv)
Definition: fuse_opt.h:123
#define FUSE_OPT_END
Definition: fuse_opt.h:104
int argc
Definition: fuse_opt.h:111
char ** argv
Definition: fuse_opt.h:114
int kernel_cache
Definition: fuse.h:240
void *(* init)(struct fuse_conn_info *conn, struct fuse_config *cfg)
Definition: fuse.h:616
unsigned long offset
Definition: fuse_opt.h:85