aboutsummaryrefslogtreecommitdiff
path: root/example
diff options
context:
space:
mode:
authorGravatar Nikolaus Rath <Nikolaus@rath.org>2016-10-10 09:38:20 -0700
committerGravatar Nikolaus Rath <Nikolaus@rath.org>2016-10-10 09:41:17 -0700
commitb69192b629a454f35eebe23d9ac4f8a5773170fd (patch)
tree9225e445a0fac5eb6566b7d383180dfae6013652 /example
parent10e718b8ca78c4e332df9d342cd662bfe3fd2bb5 (diff)
fuse_main(): extend support for printing help
There's now a way to inhibit the "usage" line (which actually got lost in commit 225c12aebf2d), which makes it easier for simply file-systems to generate good-looking --help output.
Diffstat (limited to 'example')
-rw-r--r--example/hello.c76
1 files changed, 66 insertions, 10 deletions
diff --git a/example/hello.c b/example/hello.c
index 3c24c8b..bf6ccf4 100644
--- a/example/hello.c
+++ b/example/hello.c
@@ -42,9 +42,31 @@
#include <string.h>
#include <errno.h>
#include <fcntl.h>
+#include <stddef.h>
+#include <assert.h>
-static const char *hello_str = "Hello World!\n";
-static const char *hello_path = "/hello";
+/**
+ * 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 int hello_getattr(const char *path, struct stat *stbuf)
{
@@ -54,10 +76,10 @@ static int hello_getattr(const char *path, struct stat *stbuf)
if (strcmp(path, "/") == 0) {
stbuf->st_mode = S_IFDIR | 0755;
stbuf->st_nlink = 2;
- } else if (strcmp(path, hello_path) == 0) {
+ } else if (strcmp(path+1, options.filename) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
- stbuf->st_size = strlen(hello_str);
+ stbuf->st_size = strlen(options.contents);
} else
res = -ENOENT;
@@ -77,14 +99,14 @@ static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
filler(buf, ".", NULL, 0, 0);
filler(buf, "..", NULL, 0, 0);
- filler(buf, hello_path + 1, NULL, 0, 0);
+ filler(buf, options.filename, NULL, 0, 0);
return 0;
}
static int hello_open(const char *path, struct fuse_file_info *fi)
{
- if (strcmp(path, hello_path) != 0)
+ if (strcmp(path+1, options.filename) != 0)
return -ENOENT;
if ((fi->flags & 3) != O_RDONLY)
@@ -98,14 +120,14 @@ static int hello_read(const char *path, char *buf, size_t size, off_t offset,
{
size_t len;
(void) fi;
- if(strcmp(path, hello_path) != 0)
+ if(strcmp(path+1, options.filename) != 0)
return -ENOENT;
- len = strlen(hello_str);
+ len = strlen(options.contents);
if (offset < len) {
if (offset + size > len)
size = len - offset;
- memcpy(buf, hello_str + offset, size);
+ memcpy(buf, options.contents + offset, size);
} else
size = 0;
@@ -119,7 +141,41 @@ static struct fuse_operations hello_oper = {
.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[])
{
- return fuse_main(argc, argv, &hello_oper, NULL);
+ 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] = (char*) "";
+ }
+
+ return fuse_main(args.argc, args.argv, &hello_oper, NULL);
}