2015-10-14 126 views
1

我们有一段使用Flex的C代码FILE *描述符的遗留代码。为了支持读取压缩文件到Flex,我们使用在unix文件系统中对popen使用FILE描述符时崩溃

FILE* file = popen("gzip -cd <filename>"); 

而非fopen延长了“开放”的语义打开gzip压缩文件。

我们遇到了一些问题,其中最近跨UNIX文件系统(可能安装另一个系统上使用NetApp的NFS)在尝试这使得这整个码流崩溃(段错误),我们看到的第一个消息是

gzip: stdout: Broken Pipe

和我们自己的死机架。 如果我们将该文件移动到正在运行进程的本地文件系统,则不存在段错误,并且所有内容均正常工作。

我们试过复制或修复了什么?

  • 读取使用压缩文件的gzip/bzip2的等,从内部测试NFS文件系统
  • 验证目标文件可以打开
  • “开放”的文件,并宣读了几个字节,以确保它可以打开通过这个过程

所有这些成功,但我们仍然遇到了崩溃。

我们没有想法,可以使用一些建议。

萨姆·阿普尔顿

+0

你有没有考虑过使用'zlib'? – Barmar

+0

在popen期间或稍后的命令期间是否发生段错误?你有没有试过通过valgrind运行代码?它通常可以告诉你段错误是什么。 –

+0

另外,从段错误中发布整个堆栈跟踪。它可以提供根本原因的线索。 –

回答

0

当你测试,SIGPIPE有其默认操作(杀死gzip的过程)。当进程在客户端运行时,SIGPIPE被屏蔽。下面是重现该错误的最小的程序:

#include <signal.h> 
#include <stdlib.h> 
#include <stdio.h> 

#define SZ 4096 

void mask() 
{ 
    struct sigaction sa; 
    sa.sa_handler = SIG_IGN; 
    sa.sa_flags = 0; 
    if (-1 == sigaction(SIGPIPE, &sa, 0)) 
    { 
     perror("sigaction"); 
     exit(1); 
    } 
} 

int main(int argc, char ** argv) 
{ 
    char buf[SZ]; 

#ifdef MASK 
    mask(); 
#endif 

    FILE * f = popen("gzip -dc foo.gz", "r"); 
    if (0 != fread(buf, SZ, 1, f)) 
    { 
     fwrite(buf, SZ, 1, stdout); 
    } 

    fprintf(stderr, "%d\n", pclose(f)); 
} 

而这里的输出与不MASK:

$ gcc -o foo foo.c 
$ gcc -DMASK -o foomask foo.c 
$ /foo > /dev/null 
13 
$ /foomask > /dev/null 

gzip: stdout: Broken pipe 
256 
$ 

总之,它无关NFS。那是一只红鲱鱼。

相关问题