Last active
December 5, 2020 03:26
-
-
Save furandon-pig/b9aa17f1b85b30dd15b948d588ca275e to your computer and use it in GitHub Desktop.
broccofsその1(FUSEサンプル)です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
FUSE: Filesystem in Userspace | |
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu> | |
Copyright (C) 2020 furandon_pig <furandon.pig@gmail.com> | |
This program can be distributed under the terms of the GNU GPLv2. | |
See the file COPYING. | |
*/ | |
/* | |
* gcc -g -o brocco brocco.c `pkg-config fuse3 --cflags --libs` | |
*/ | |
#define FUSE_USE_VERSION 31 | |
#include <fuse.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <errno.h> | |
#include <fcntl.h> | |
#include <stddef.h> | |
#include <assert.h> | |
static struct options { | |
const char *filename; | |
const char *contents; | |
int show_help; | |
int count; | |
int max; | |
char **messages; | |
} options; | |
#define OPTION(t, p) \ | |
{ t, offsetof(struct options, p), 1 } | |
static const struct fuse_opt option_spec[] = { | |
FUSE_OPT_END | |
}; | |
static void *hello_init(struct fuse_conn_info *conn, | |
struct fuse_config *cfg) | |
{ | |
(void) conn; | |
cfg->kernel_cache = 0; // OS側でデータをキャッシュさせない。 | |
return NULL; | |
} | |
static int hello_getattr(const char *path, struct stat *stbuf, | |
struct fuse_file_info *fi) | |
{ | |
(void) fi; | |
int res = 0; | |
memset(stbuf, 0, sizeof(struct stat)); | |
if (strcmp(path, "/") == 0) { | |
stbuf->st_mode = S_IFDIR | 0755; | |
stbuf->st_nlink = 2; | |
} else if (strcmp(path+1, options.filename) == 0) { | |
stbuf->st_mode = S_IFREG | 0444; | |
stbuf->st_nlink = 1; | |
stbuf->st_size = strlen(options.contents); | |
} else | |
res = -ENOENT; | |
return res; | |
} | |
static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, | |
off_t offset, struct fuse_file_info *fi, | |
enum fuse_readdir_flags flags) | |
{ | |
(void) offset; | |
(void) fi; | |
(void) flags; | |
if (strcmp(path, "/") != 0) | |
return -ENOENT; | |
filler(buf, ".", NULL, 0, 0); | |
filler(buf, "..", 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+1, options.filename) != 0) | |
return -ENOENT; | |
if ((fi->flags & O_ACCMODE) != O_RDONLY) | |
return -EACCES; | |
return 0; | |
} | |
static int hello_read(const char *path, char *buf, size_t size, off_t offset, | |
struct fuse_file_info *fi) | |
{ | |
size_t len; | |
(void) fi; | |
if(strcmp(path+1, options.filename) != 0) | |
return -ENOENT; | |
len = strlen(options.contents); | |
memcpy(buf, options.contents, len); | |
if (++(options.count) >= options.max) { | |
options.count = 0; | |
} | |
// 参照するデータを切り替える。 | |
options.contents = options.messages[options.count]; | |
return size; | |
} | |
static const struct fuse_operations hello_oper = { | |
.init = hello_init, | |
.getattr = hello_getattr, | |
.readdir = hello_readdir, | |
.open = hello_open, | |
.read = hello_read, | |
}; | |
int main(int argc, char *argv[]) | |
{ | |
int ret; | |
struct fuse_args args = FUSE_ARGS_INIT(argc, argv); | |
// FUSEマウント時に表示させるファイル名を設定。 | |
options.filename = strdup("brocco.txt"); | |
// 「ブロ子の歌」データ。 | |
char *messages[] = { | |
"ブロっ子\n", | |
"ブロっ子\n", | |
"ブロッコリー♪\n", | |
"(ブロっ子)\n", | |
NULL | |
}; | |
// 歌詞データの行数をカウントする。 | |
for (options.max = 0; messages[options.max] != NULL; options.max++) | |
; | |
// 歌詞データをstrdup()したうえで設定する。 | |
options.messages = malloc(sizeof(char *) * options.count); | |
if (options.messages) { | |
for (int i = 0; i < options.max; i++) { | |
options.messages[i] = strdup(messages[i]); | |
} | |
} | |
options.count = 0; | |
options.contents = options.messages[0]; | |
/* Parse options */ | |
if (fuse_opt_parse(&args, &options, option_spec, NULL) == -1) | |
return 1; | |
ret = fuse_main(args.argc, args.argv, &hello_oper, NULL); | |
fuse_opt_free_args(&args); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment