我们有一段使用Flex和C风格FILE *描述符的遗留代码。为了支持将压缩文件读入Flex,我们使用
扩展了“开放”语义以打开gzip的文件。FILE* file = popen("gzip -cd <filename>");
而不是fopen
。
我们最近遇到了一些问题,在unix文件系统上尝试这个问题(可能是在NetApp上使用NFS挂载的另一个文件系统)会导致整个代码流崩溃(segfault),我们看到的第一条消息是
gzip:stdout:Broken Pipe
和我们自己的崩溃框架。 如果我们获取文件并将其移动到运行进程的本地文件系统,则没有段错误,一切正常。
我们试图复制或修复什么?
所有这些都成功了,但我们仍然遇到了崩溃。
我们缺乏想法,可以使用一些建议。
Sam Appleton
答案 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无关。那是一只红鲱鱼。