2011-04-01 108 views
1

我遇到了一些问题,并且找不到解决方案:/我需要在我的保险丝文件系统中打开文本文件。在调试一切正常,但在发布系统崩溃。我用这个做了一个简单的例子。有人可以告诉这个代码有什么问题吗?FUSE文件系统在打开文件时崩溃(仅在发布模式下)

/* 
    FUSE: Filesystem in Userspace 
    Copyright (C) 2001-2007 Miklos Szeredi <[email protected]> 

    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 <[email protected]> 

    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); 
} 
+0

下次为自己节省一些麻烦,并使用编辑器中的“{}”按钮来设置代码的格式。 – Mat 2011-04-01 10:06:04

+0

好的,对不起,下次我会这样做。 – krzysztof 2011-04-01 10:31:04

+0

你能更具体地了解这次事故吗?给回溯?将它失败的区域拧紧? – Mat 2011-04-01 11:00:47

回答

0

您的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失败,您应该错误(或只是离开)此功能。否则,下一行将调用fgetsNULL作为其文件参数。

0

好吧,我已经找到了解决办法,路径必须是绝对文件路径(不知道是这是正确的句子),但这里是示例代码,这是在释放工作以及在调试:

/* 
    FUSE: Filesystem in Userspace 
    Copyright (C) 2001-2007 Miklos Szeredi <[email protected]> 

    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); 
} 
+1

如果这是解决方案,请将其标记为这样。另外,为什么在差异足够的时候发布相同的庞大代码blob? – 2011-04-01 17:06:57