2 FUSE fioc: FUSE ioctl example
3 Copyright (C) 2008 SUSE Linux Products GmbH
4 Copyright (C) 2008 Tejun Heo <teheo@suse.de>
6 This program can be distributed under the terms of the GNU GPL.
9 gcc -Wall fioc.c `pkg-config fuse --cflags --libs` -o fioc
12 #define FUSE_USE_VERSION 26
24 #define FIOC_NAME "fioc"
32 static void *fioc_buf;
33 static size_t fioc_size;
35 static int fioc_resize(size_t new_size)
39 if (new_size == fioc_size)
42 new_buf = realloc(fioc_buf, new_size);
43 if (!new_buf && new_size)
46 if (new_size > fioc_size)
47 memset(new_buf + fioc_size, 0, new_size - fioc_size);
55 static int fioc_expand(size_t new_size)
57 if (new_size > fioc_size)
58 return fioc_resize(new_size);
62 static int fioc_file_type(const char *path)
64 if (strcmp(path, "/") == 0)
66 if (strcmp(path, "/" FIOC_NAME) == 0)
71 static int fioc_getattr(const char *path, struct stat *stbuf)
73 stbuf->st_uid = getuid();
74 stbuf->st_gid = getgid();
75 stbuf->st_atime = stbuf->st_mtime = time(NULL);
77 switch (fioc_file_type(path)) {
79 stbuf->st_mode = S_IFDIR | 0755;
83 stbuf->st_mode = S_IFREG | 0644;
85 stbuf->st_size = fioc_size;
94 static int fioc_open(const char *path, struct fuse_file_info *fi)
98 if (fioc_file_type(path) != FIOC_NONE)
103 static int fioc_do_read(char *buf, size_t size, off_t offset)
105 if (offset >= fioc_size)
108 if (size > fioc_size - offset)
109 size = fioc_size - offset;
111 memcpy(buf, fioc_buf + offset, size);
116 static int fioc_read(const char *path, char *buf, size_t size,
117 off_t offset, struct fuse_file_info *fi)
121 if (fioc_file_type(path) != FIOC_FILE)
124 return fioc_do_read(buf, size, offset);
127 static int fioc_do_write(const char *buf, size_t size, off_t offset)
129 if (fioc_expand(offset + size))
132 memcpy(fioc_buf + offset, buf, size);
137 static int fioc_write(const char *path, const char *buf, size_t size,
138 off_t offset, struct fuse_file_info *fi)
142 if (fioc_file_type(path) != FIOC_FILE)
145 return fioc_do_write(buf, size, offset);
148 static int fioc_truncate(const char *path, off_t size)
150 if (fioc_file_type(path) != FIOC_FILE)
153 return fioc_resize(size);
156 static int fioc_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
157 off_t offset, struct fuse_file_info *fi)
162 if (fioc_file_type(path) != FIOC_ROOT)
165 filler(buf, ".", NULL, 0);
166 filler(buf, "..", NULL, 0);
167 filler(buf, FIOC_NAME, NULL, 0);
172 static int fioc_ioctl(const char *path, int cmd, void *arg,
173 struct fuse_file_info *fi, unsigned int flags, void *data)
179 if (fioc_file_type(path) != FIOC_FILE)
182 if (flags & FUSE_IOCTL_COMPAT)
187 *(size_t *)data = fioc_size;
191 fioc_resize(*(size_t *)data);
198 static struct fuse_operations fioc_oper = {
199 .getattr = fioc_getattr,
200 .readdir = fioc_readdir,
201 .truncate = fioc_truncate,
208 int main(int argc, char *argv[])
210 return fuse_main(argc, argv, &fioc_oper, NULL);