2011-04-01 140 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