gpt4 book ai didi

c - FUSE 文件系统在打开文件时崩溃(仅在 Release模式下)

转载 作者:太空宇宙 更新时间:2023-11-04 04:57:09 25 4
gpt4 key购买 nike

我有一些问题,我找不到解决方案:/我需要在我的 fuse 文件系统中打开一个文本文件。在调试中一切正常,但在发布系统中崩溃。我用这个做了一个简单的例子。有人能说出这段代码有什么问题吗?

/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>

This program can be distributed under the terms of the GNU GPL.
See the file COPYING.

gcc -Wall `pkg-config fuse --cflags --libs` hello.c -o hello
*/
# define FUSE_USE_VERSION 26

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

void stripnl(char *str) {
while(strlen(str) && ( (str[strlen(str) - 1] == 13) ||
( str[strlen(str) - 1] == 10 ))) {
str[strlen(str) - 1] = 0;
}
}

static const char *hello_str = "Hello World!\n";
static const char *hello_path = "/hello";

static int hello_getattr(const char *path, struct stat *stbuf)
{
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, hello_path) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(hello_str);
} 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)
{
(void) offset;
(void) fi;

if (strcmp(path, "/") != 0)
return -ENOENT;

filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);

filler(buf, hello_path + 1, NULL, 0);

FILE *infile;
char fname[40];
char line[100];
int lcount;

/* We need to get rid of the newline char. */
stripnl(fname);

/* Open the file. If NULL is returned there was an error */
if((infile = fopen("ex.txt", "r")) == NULL) {
printf("Error Opening File.\n");
}

while( fgets(line, sizeof(line), infile) != NULL ) {
/* Get each line from the infile */
lcount++;
/* print the line number and data */
printf("Line %d: %s", lcount, line);
filler(buf, line, NULL, 0);
}

fclose(infile); /* Close the file */

return 0;
}

static int hello_open(const char *path, struct fuse_file_info *fi)
{
if (strcmp(path, hello_path) != 0)
return -ENOENT;

if ((fi->flags & 3) != 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, hello_path) != 0)
return -ENOENT;

len = strlen(hello_str);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, hello_str + offset, size);
} else
size = 0;

return size;
}

static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};

int main(int argc, char *argv[])
{
return fuse_main(argc, argv, &hello_oper, NULL);
}

更新

好的,我找到了解决方案,路径必须是绝对文件路径(不确定这句话是否正确),但这里是示例代码,它在发布和调试中都有效:

/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>

This program can be distributed under the terms of the GNU GPL.
See the file COPYING.

gcc -Wall `pkg-config fuse --cflags --libs` hello.c -o hello
*/
# define FUSE_USE_VERSION 26

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

void stripnl(char *str) {
while(strlen(str) && ( (str[strlen(str) - 1] == 13) ||
( str[strlen(str) - 1] == 10 ))) {
str[strlen(str) - 1] = 0;
}
}

static const char *hello_str = "Hello World!\n";
static const char *hello_path = "/hello";

static int hello_getattr(const char *path, struct stat *stbuf)
{
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, hello_path) == 0) {
stbuf->st_mode = S_IFREG | 0444;
stbuf->st_nlink = 1;
stbuf->st_size = strlen(hello_str);
} 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)
{
(void) offset;
(void) fi;

if (strcmp(path, "/") != 0)
return -ENOENT;

filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);

filler(buf, hello_path + 1, NULL, 0);

FILE *infile;
char line[100];

if((infile = fopen("/root/Desktop/fexamples/ex.txt", "rb")) == NULL)
{
return -1;
}

while( fgets(line, sizeof(line), infile) != NULL )
{
filler(buf, line, NULL, 0);
}

fclose(infile); /* Close the file */

return 0;
}

static int hello_open(const char *path, struct fuse_file_info *fi)
{
if (strcmp(path, hello_path) != 0)
return -ENOENT;

if ((fi->flags & 3) != 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, hello_path) != 0)
return -ENOENT;

len = strlen(hello_str);
if (offset < len) {
if (offset + size > len)
size = len - offset;
memcpy(buf, hello_str + offset, size);
} else
size = 0;

return size;
}

static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};

int main(int argc, char *argv[])
{
return fuse_main(argc, argv, &hello_oper, NULL);
}

最佳答案

您的 readdir 实现中至少有两个问题。

char fname[40];
char line[100];
int lcount;

/* We need to get rid of the newline char. */
stripnl(fname);

您正在对您未在任何地方初始化的 fname 的内容进行操作。这几乎可以做任何事情。在那之后您没有使用 fname 的事实是无关紧要的,您可以使用该 stripnl 调用修改完全随机的数据。

/* Open the file.  If NULL is returned there was an error */
if((infile = fopen("ex.txt", "r")) == NULL) {
printf("Error Opening File.\n");
}

如果 fopen 失败,您应该错误地退出(或直接离开)这个函数。否则,下一行将以 NULL 作为文件参数调用 fgets

关于c - FUSE 文件系统在打开文件时崩溃(仅在 Release模式下),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5511841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com