fclose后管道“关闭”()
int fd[2];
void write_to_pipe(char* str)
{
int file = fd[1];
FILE *stream;
//printf("writing to pipe : %s\n", str);
stream = fdopen(file, "w");
//printf("fdopen returned : %d\n",(int)stream);
fprintf(stream, "%s", str);
fclose(stream);
}
At main() : pipe(fd);
如果我先打电话write_to_pipe
,那么它工作得很好。fclose后管道“关闭”()
如果第二次调用该函数,则fdopen
失败(返回0)。
我以为流/管/财产以后被关闭
什么是安全的方式,以“不关闭管道”和调用函数多次
编译器:GCC 6.3.1
ps 这个阅读功能也可能有类似的问题。
char* read_from_pipe()
{
int file = fd[0];
static char buf[100];
FILE *stream;
stream = fdopen(file, "r");
read(file,buf,100);
fclose(stream);
return buf;
}
什么是安全的方式,以“不关闭管道”和调用函数多次
不要在文件描述符使用fdopen()
:
void write_to_pipe(char* str)
{
write(fd[ 1 ], str, strlen(str));
}
或使用fdopen()
与管本身的范围相同:
int fd[2];
.
.
.
FILE *stream = fdopen(fd[ 1 ]);
.
.
.
void write_to_pipe(char* str)
{
fprintf(stream, "%s", str);
}
您正在关闭关闭管道的stdout文件描述符。打开它一次,并保持它,直到你完成。
您可能dup
的文件描述符并在复制上执行fdopen
。
int write_to_pipe(char* str)
{
int file = dup(fd[1]);
if(0>file)
return -1;
FILE *stream;
//...
}
在任何情况下,您的函数应该可能返回一个整数,以便它可以表示函数内可能发生的可能错误。
标准C不知道POSIX文件描述符,只有FILE *
是标准的,fclose()
关闭文件。这当然意味着在平台上做任何必要的操作来关闭文件,所以在这种情况下,在底层描述符上调用close()
。
你应该做的只是在适当的地方使用FILE *
。因此,如果在创建管道后立即需要管道作为您的FILE *
,fdopen()
的后端。这样,您就可以在一个地方使用特定于平台的代码。
如果您碰巧需要文件描述符来关闭管道以外的任何其他功能,可以在FILE *
上使用fileno()
,但在代码中有另一个与平台相关的部件。
此功能:
char* read_from_pipe()
{
int file = fd[0];
static char buf[100];
FILE *stream;
stream = fdopen(file, "r");
read(file,buf,100);
fclose(stream);
return buf;
}
包含几个问题。
建议写它类似于:
#define MAX_BUF_LEN 100
char* read_from_pipe()
{
static char buf[ MAX_BUF_LEN +1 ];
ssize_t byteCount = read(fd[0], buf, MAX_BUF_LEN);
if(0 > byteCount)
{ // an error occurred
perror("read from pipe failed");
buf[0] = '\0';
}
else if(0 == byteCount)
{
fprintf(stderr, "no bytes read\n");
buf[0] = '\0';
}
else
{
buf[byteCount] = '\0';
}
return buf;
} // end function: read_from_pipe
注:read()
不会终止字符数组,所以代码必须做到这一点,数组必须是1个字符长度超过字符问的最大数量因为在read()
声明中。
注意:read()
的语法需要int
,而不是FILE*
作为其第一个参数。下面是正确的语法:
ssize_t read(int fd, void *buf, size_t count);
此功能:
int fd[2];
void write_to_pipe(char* str)
{
int file = fd[1];
FILE *stream;
//printf("writing to pipe : %s\n", str);
stream = fdopen(file, "w");
//printf("fdopen returned : %d\n",(int)stream);
fprintf(stream, "%s", str);
fclose(stream);
}
极不理想很多。
建议添加类似的东西:
int fd[2]; << in file scope, so visible from functions
void write_to_pipe(char* str)
{
//printf("writing to pipe : %s\n", str);
ssize_t bytesWritten = write(fd[1], str, strlen(str));
if(strlen(str) != bytesWritten)
{
fprintf(stderr, "write to pipe failed to write all bytes\n");
}
else if(0 > bytesWritten)
{
perror("write to pipe failed");
}
} // end function: write_to_pipe
你'read_from_pipe()'有很多比关闭文件描述符更大的问题。你在'FILE *'中调用'read()'。这根本不起作用。 'read()'直接获取一个文件描述符,并且它不会NUL终止它所读取的内容。 –
你应该使用[popen(3)](http://man7.org/linux/man-pages/man3/popen.3.html)和'pclose' –
@BasileStarynkevitch但是'popen()'不会提供一个双向管道。它是只读或只写的。 –