FUSE Driver Example
FUSE(Filesystem in Userspace) driver¿¡ ´ëÇÑ ¿¹Á¦ ¶
¼³¸í ¶
¿¹Á¦¼Ò½º main.c ¶
/*
Copyright (C) JAEHYUK CHO
All rights reserved.
Code by JaeHyuk Cho <mailto:minzkn@minzkn.com>
*/
#if !defined(FUSE_USE_VERSION)
# define FUSE_USE_VERSION 26
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <fuse.h>
#if !defined(mzfuse_virtual_filesystem_t)
typedef struct mzfuse_virtual_filesystem_ts {
const char *m_pathname;
const unsigned char *m_data;
}__mzfuse_virtual_filesystem_t;
# define mzfuse_virtual_filesystem_t __mzfuse_virtual_filesystem_t
#endif
int main(int s_argc, char **s_argv);
static int mzfuse_getattr(const char *s_pathname, struct stat *s_statbuffer);
static int mzfuse_open(const char *s_pathname, struct fuse_file_info *s_fileinfo);
static int mzfuse_read(const char *s_pathname, char *s_data, size_t s_size, off_t s_offset, struct fuse_file_info *s_fileinfo);
static int mzfuse_readdir(const char *s_pathname, void *s_buffer, fuse_fill_dir_t s_filler, off_t s_offset, struct fuse_file_info *s_fileinfo);
static mzfuse_virtual_filesystem_t g_mzfuse_virtual_filesystem[] = {
{"/.", (const unsigned char *)0},
{"/..", (const unsigned char *)0},
{"/TEST FILE 00", (const unsigned char *)"VIRTUAL DATA 00"},
{"/TEST FILE 01", (const unsigned char *)"VIRTUAL DATA 01"},
{"/TEST FILE 02", (const unsigned char *)"VIRTUAL DATA 02"},
{"/TEST FILE 03", (const unsigned char *)"VIRTUAL DATA 03"},
{(const char *)0, (const unsigned char *)0}
};
static struct fuse_operations g_mzfuse_operations = {
/* int (*getattr) (const char *, struct stat *); */
.getattr = mzfuse_getattr,
/* int (*readlink) (const char *, char *, size_t); */
/* int (*getdir) (const char *, fuse_dirh_t, fuse_dirfil_t); */
/* int (*mknod) (const char *, mode_t, dev_t); */
/* int (*mkdir) (const char *, mode_t); */
/* int (*unlink) (const char *); */
/* int (*rmdir) (const char *); */
/* int (*symlink) (const char *, const char *); */
/* int (*rename) (const char *, const char *); */
/* int (*link) (const char *, const char *); */
/* int (*chmod) (const char *, mode_t); */
/* int (*chown) (const char *, uid_t, gid_t); */
/* int (*truncate) (const char *, off_t); */
/* int (*utime) (const char *, struct utimbuf *); */
/* int (*open) (const char *, struct fuse_file_info *); */
.open = mzfuse_open,
/* int (*read) (const char *, char *, size_t, off_t, struct fuse_file_info *); */
.read = mzfuse_read,
/* int (*write) (const char *, const char *, size_t, off_t, struct fuse_file_info *); */
/* int (*statfs) (const char *, struct statvfs *); */
/* int (*flush) (const char *, struct fuse_file_info *); */
/* int (*release) (const char *, struct fuse_file_info *); */
/* int (*fsync) (const char *, int, struct fuse_file_info *); */
/* int (*setxattr) (const char *, const char *, const char *, size_t, int); */
/* int (*getxattr) (const char *, const char *, char *, size_t); */
/* int (*listxattr) (const char *, char *, size_t); */
/* int (*removexattr) (const char *, const char *); */
/* int (*opendir) (const char *, struct fuse_file_info *); */
/* int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t, struct fuse_file_info *); */
.readdir = mzfuse_readdir,
/* int (*releasedir) (const char *, struct fuse_file_info *); */
/* int (*fsyncdir) (const char *, int, struct fuse_file_info *); */
/* void *(*init) (struct fuse_conn_info *conn); */
/* void (*destroy) (void *); */
/* int (*access) (const char *, int); */
/* int (*create) (const char *, mode_t, struct fuse_file_info *); */
/* int (*ftruncate) (const char *, off_t, struct fuse_file_info *); */
/* int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *); */
/* int (*lock) (const char *, struct fuse_file_info *, int cmd, struct flock *); */
/* int (*utimens) (const char *, const struct timespec tv[2]); */
/* int (*bmap) (const char *, size_t blocksize, uint64_t *idx); */
/* unsigned int flag_nullpath_ok : 1; */
/* unsigned int flag_reserved : 31; */
/* int (*ioctl) (const char *, int cmd, void *arg, struct fuse_file_info *, unsigned int flags, void *data); */
/* int (*poll) (const char *, struct fuse_file_info *, struct fuse_pollhandle *ph, unsigned *reventsp); */
};
static int mzfuse_getattr(const char *s_pathname, struct stat *s_statbuffer)
{
int s_index = 0;
(void)memset((void *)s_statbuffer, 0, sizeof(struct stat));
if(strcmp(s_pathname, "/") == 0) {
s_statbuffer->st_mode = S_IFDIR | 0755;
s_statbuffer->st_nlink = 2;
return(0);
}
while(g_mzfuse_virtual_filesystem[s_index].m_pathname != ((const char *)0)) {
if(strcmp(s_pathname, g_mzfuse_virtual_filesystem[s_index].m_pathname) == 0) {
break;
}
++s_index;
}
if(g_mzfuse_virtual_filesystem[s_index].m_pathname == ((const char *)0)) {
return(-ENOENT);
}
s_statbuffer->st_mode = S_IFREG | 0444;
s_statbuffer->st_nlink = 1;
s_statbuffer->st_size = strlen("TEST DATA");
return(0);
}
static int mzfuse_open(const char *s_pathname, struct fuse_file_info *s_fileinfo)
{
int s_index = 0;
while(g_mzfuse_virtual_filesystem[s_index].m_pathname != ((const char *)0)) {
if(strcmp(s_pathname, g_mzfuse_virtual_filesystem[s_index].m_pathname) == 0) {
break;
}
++s_index;
}
if(g_mzfuse_virtual_filesystem[s_index].m_pathname == ((const char *)0)) {
return(-ENOENT);
}
if((s_fileinfo->flags & O_RDONLY) != O_RDONLY) {
return(-EACCES);
}
return(0);
}
static int mzfuse_read(const char *s_pathname, char *s_data, size_t s_size, off_t s_offset, struct fuse_file_info *s_fileinfo)
{
off_t s_result;
int s_index = 0;
while(g_mzfuse_virtual_filesystem[s_index].m_pathname != ((const char *)0)) {
if(strcmp(s_pathname, g_mzfuse_virtual_filesystem[s_index].m_pathname) == 0) {
break;
}
++s_index;
}
if(g_mzfuse_virtual_filesystem[s_index].m_pathname == ((const char *)0)) {
return(-ENOENT);
}
s_result = strlen((const char *)g_mzfuse_virtual_filesystem[s_index].m_data);
if(s_offset >= s_result) {
return(0);
}
if(s_result < (s_offset + ((off_t)s_size))) {
s_size = (size_t)(s_result - s_offset);
}
(void)memcpy((void *)s_data, (const void *)(&g_mzfuse_virtual_filesystem[s_index].m_data[s_offset]), s_size);
return(s_result);
}
static int mzfuse_readdir(const char *s_pathname, void *s_buffer, fuse_fill_dir_t s_filler, off_t s_offset, struct fuse_file_info *s_fileinfo)
{
int s_index = 0;
if(strcmp(s_pathname, "/") != 0) {
return(-ENOENT);
}
while(g_mzfuse_virtual_filesystem[s_index].m_pathname != ((const char *)0)) {
/* typedef int (*fuse_fill_dir_t) (void *buf, const char *name, const struct stat *stbuf, off_t off); */
s_filler(s_buffer, (const char *)(&g_mzfuse_virtual_filesystem[s_index].m_pathname[1]), (const struct stat *)0, (off_t)0);
++s_index;
}
return(0);
}
int main(int s_argc, char **s_argv)
{
/* int fuse_main(int argc, char *argv[], const struct fuse_operations *op, void *user_data); */
return(fuse_main(s_argc, s_argv, (const struct fuse_operations *)(&g_mzfuse_operations), (void *)0));
}
/* End of source */
makefile ¶# Copyright (C) JAEHYUK CHO # All rights reserved. # Code by JaeHyuk Cho <mailto:minzkn@minzkn.com> CROSS_COMPILE ?=# CC := $(CROSS_COMPILE)gcc# RM := rm -f# STRIP := $(CROSS_COMPILE)strip# THIS_NAME := mzfusetest# CFLAGS := -Os -pipe# CFLAGS += -Wall -Werror# CFLAGS += -fomit-frame-pointer# #CFLAGS += -ansi# CFLAGS += -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64# CFLAGS += -I.# LDFLAGS := -s -lfuse# TARGET := $(THIS_NAME)# #OBJECTS := $(THIS_NAME).o# OBJECTS := main.o# .PHONY: all clean all: $(TARGET) ; $(STRIP) --remove-section=.comment --remove-section=.note $(TARGET) clean: ; $(RM) *.o $(TARGET) $(TARGET): $(OBJECTS) ; $(CC) $(LDFLAGS) -o $(@) $(^) $(OBJECTS): makefile %.o: %.c ; $(CC) $(CFLAGS) -c -o $(@) $(<) # End of Makefile |
You will have long and healthy life. |