xref: /third_party/libfuse/example/null.c (revision 6881f68f)
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
9/** @file
10 *
11 * This "filesystem" provides only a single file. The mountpoint
12 * needs to be a file rather than a directory. All writes to the
13 * file will be discarded, and reading the file always returns
14 * \0.
15 *
16 * Compile with:
17 *
18 *     gcc -Wall null.c `pkg-config fuse3 --cflags --libs` -o null
19 *
20 * ## Source code ##
21 * \include passthrough_fh.c
22 */
23
24
25#define FUSE_USE_VERSION 31
26
27#include <fuse.h>
28#include <fuse_lowlevel.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
33#include <time.h>
34#include <errno.h>
35
36static int null_getattr(const char *path, struct stat *stbuf,
37			struct fuse_file_info *fi)
38{
39	(void) fi;
40
41	if(strcmp(path, "/") != 0)
42		return -ENOENT;
43
44	stbuf->st_mode = S_IFREG | 0644;
45	stbuf->st_nlink = 1;
46	stbuf->st_uid = getuid();
47	stbuf->st_gid = getgid();
48	stbuf->st_size = (1ULL << 32); /* 4G */
49	stbuf->st_blocks = 0;
50	stbuf->st_atime = stbuf->st_mtime = stbuf->st_ctime = time(NULL);
51
52	return 0;
53}
54
55static int null_truncate(const char *path, off_t size,
56			 struct fuse_file_info *fi)
57{
58	(void) size;
59	(void) fi;
60
61	if(strcmp(path, "/") != 0)
62		return -ENOENT;
63
64	return 0;
65}
66
67static int null_open(const char *path, struct fuse_file_info *fi)
68{
69	(void) fi;
70
71	if(strcmp(path, "/") != 0)
72		return -ENOENT;
73
74	return 0;
75}
76
77static int null_read(const char *path, char *buf, size_t size,
78		     off_t offset, struct fuse_file_info *fi)
79{
80	(void) buf;
81	(void) offset;
82	(void) fi;
83
84	if(strcmp(path, "/") != 0)
85		return -ENOENT;
86
87	if (offset >= (1ULL << 32))
88		return 0;
89
90	memset(buf, 0, size);
91	return size;
92}
93
94static int null_write(const char *path, const char *buf, size_t size,
95		      off_t offset, struct fuse_file_info *fi)
96{
97	(void) buf;
98	(void) offset;
99	(void) fi;
100
101	if(strcmp(path, "/") != 0)
102		return -ENOENT;
103
104	return size;
105}
106
107static const struct fuse_operations null_oper = {
108	.getattr	= null_getattr,
109	.truncate	= null_truncate,
110	.open		= null_open,
111	.read		= null_read,
112	.write		= null_write,
113};
114
115int main(int argc, char *argv[])
116{
117	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
118	struct fuse_cmdline_opts opts;
119	struct stat stbuf;
120
121	if (fuse_parse_cmdline(&args, &opts) != 0)
122		return 1;
123	fuse_opt_free_args(&args);
124
125	if (!opts.mountpoint) {
126		fprintf(stderr, "missing mountpoint parameter\n");
127		return 1;
128	}
129
130	if (stat(opts.mountpoint, &stbuf) == -1) {
131		fprintf(stderr ,"failed to access mountpoint %s: %s\n",
132			opts.mountpoint, strerror(errno));
133		free(opts.mountpoint);
134		return 1;
135	}
136	free(opts.mountpoint);
137	if (!S_ISREG(stbuf.st_mode)) {
138		fprintf(stderr, "mountpoint is not a regular file\n");
139		return 1;
140	}
141
142	return fuse_main(argc, argv, &null_oper, NULL);
143}
144