我正在尝试使用fuse实现文件系统。需要为"读取目录"实现的fuse_operations的功能是什么?和"读取文件"操作
我尝试通过在网上学习一些教程来实现它,但是无法完全理解它(bbfs文件系统教程https://www.cs.nmsu.edu/~pfeiffer/fuse-tutorial/)并且我的代码给出了分段错误?
#define FUSE_USE_VERSION 30
#include <stdio.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fuse.h>
#include <string.h>
#include <libgen.h>
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/xattr.h>
struct uafs_state {
char *rootdir;
};
#define UAFS_DATA ((struct uafs_state *) fuse_get_context()->private_data)
static void uafs_fullpath(char fpath[PATH_MAX], const char *path)
{
strcpy(fpath, UAFS_DATA->rootdir);
strncat(fpath, path, PATH_MAX);
}
int error_check(int retstat)
{
if (retstat < 0) {
retstat = -errno;
}
return retstat;
}
int uafs_getattr(const char *path, struct stat *buf)
{
printf("Reading Attributes.........\n");
int retstat;
char fpath[PATH_MAX];
uafs_fullpath(fpath, path);
retstat = error_check(lstat(fpath, buf));
return retstat;
}
int uafs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
{
printf("Reading Directory.....\n");
int retstat = 0;
DIR *dp;
struct dirent *de;
dp = (DIR *) (uintptr_t) fi->fh;
de = readdir(dp);
if (de == 0) {
retstat = -errno;
return retstat;
}
do {
if (filler(buf, de->d_name, NULL, 0) != 0) {
return -ENOMEM;
}
} while ((de == readdir(dp)) != NULL);
return retstat;
}
int uafs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
{
printf("Reading file.....\n");
int retstat = 0;
retstat = pread(fi->fh, buf, size, offset);
return error_check(retstat);
}
struct fuse_operations uafs_oper = {
.getattr = uafs_getattr,
.readdir = uafs_readdir,
.read = uafs_read,
};
int main(int argc, char *argv[])
{
int fuse_stat;
struct uafs_state *uafs_data;
if ((getuid() == 0) || (geteuid() == 0)) {
printf("Error\n");
return 1;
}
if ((argc < 3) || (argv[argc-2][0] == '-') || (argv[argc-1][0] == '-')) {
abort();
}
uafs_data = malloc(sizeof(struct uafs_state));
if (uafs_data == NULL) {
abort();
}
uafs_data->rootdir = realpath(argv[argc-2], NULL);
argv[argc-2] = argv[argc-1];
argv[argc-1] = NULL;
fuse_stat = fuse_main(argc, argv, &uafs_oper, uafs_data);
return fuse_stat;
}