2013-11-22 115 views
0

我有在C.通过管道传送二进制数据C

我的程序创建两个子进程(silblings)以及两个管道的子进程和管道的问题。父亲从stdin中读取并通过第一管道发送数据。第一个孩子将stdin重定向到第一个管道,将stdout重定向到第二个管道。之后,小孩用execlp(3)运行gzip -cf。第二个孩子从第二个管道读取并将数据写入stdout(或文件中)。

我试过了,但它不适用于二进制数据。如果第一个孩子只通过第二根管道发送文本数据(不使用gzip)并且第二个孩子读取它,则程序工作正常。但是,如果我使用gzip execlp()并且该进程写入二进制数据,程序不起作用,因为我没有获取所有数据。

下面是代码的一部分:

第一个孩子:

/* Close the pipe-ends which are not needed [...] */ 
/* Redirect the stdin and stdout with dup2 [...] */ 

if(execlp(EXEC,EXEC_ARG0,EXEC_ARG1,(char*) 0) == -1) /* run execlp with 'gzip -cf' */ 
    bail_out(EXIT_FAILURE,"Child_1: Cannot execute "EXEC_ARG0" "EXEC_ARG1"!"); 

老二:

/* Close the pipe-ends which are not needed [...] */ 

FILE *fd = NULL; 
char str[4096]; 

fd = fdopen(pipefd_com2[0],"rb"); 
(void) fread(str,sizeof(str),1,fd); /* read from pipe */ 
(void) fclose(fd); 

FILE *fw = NULL; 

if(file_arg == NULL) /* check if there was a file as argument */ 
    fw = stdout; 
else 
    fw = fopen(file_arg,"wb"); 

if(fw == NULL) 
    bail_out(EXIT_FAILURE,"Failed to write file!"); /* does not return */ 

(void) fwrite(str,strlen(str),1,fw); /* write to stdout or file */ 
(void) fclose(fw); 
+1

故意施放到虚空中的代码来压制无论从任何静态分析,仔细检查你的代码未检查返回值警告是特别不方便,因为至少在一个情况下** **不检查这些值是你的问题的一部分。 – WhozCraig

回答

2

strlen函数是C风格的字符串,而不是二进制数据。另外,您的参数fread是错误的。第二个参数是您正在阅读的每个对象的大小。对于任意的二进制数据,应该是1,因为每个对象都是一个字节。这将使您读取的字节数为fread的返回值,这是您需要传递给fwrite作为第三个参数。

总之:

size_t bytes_read; 
// ... 
bytes_read = fread(str,1,sizeof(str),fd); /* read from pipe */ 
// ... 
(void) fwrite(str,1,bytes_read,fw); /* write to stdout or file */ 

您也应该检查从fread的返回值。

+0

非常感谢!有用。 –

相关问题