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
,那么它的效果非常好。
如果第二次调用该函数,则fdopen
失败(返回0)。
我假设流/管道/ somthing已关闭
“不关闭管道”并多次调用该函数的安全方法是什么
编译器:gcc 6.3.1
P.S。 这个读取功能也可能有类似的问题。
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;
}
答案 0 :(得分:2)
标准C不知道POSIX文件描述符,只有FILE *
是标准的,fclose()
关闭文件。这当然意味着在平台上做任何必要的事情来关闭文件,所以在这种情况下,在底层描述符上调用close()
。
您应该做的只是在适当的地方使用FILE *
。因此,如果您在创建管道后立即需要管道作为FILE *
,fdopen()
文件的后端。这样,您就可以在一个地方拥有特定于平台的代码。
如果你碰巧需要文件描述符而不是关闭管道,你可以在fileno()
上使用FILE *
,但是你的代码中还有另一个与平台相关的部分。
答案 1 :(得分:1)
您可以dup
文件描述符并在副本上执行fdopen
。
int write_to_pipe(char* str)
{
int file = dup(fd[1]);
if(0>file)
return -1;
FILE *stream;
//...
}
在任何情况下,您的函数都应该返回一个整数,以便它可以指示函数内部可能发生的错误。
答案 2 :(得分:1)
没有关闭管道的安全方法是什么?并多次调用该函数
不要在文件描述符上使用#!/bin/bash
sed -i -e '/.*tour\.html\|.*Thumb[^\/]*\.jpg/!d' "$1"
:
fdopen()
或在与管道本身相同的范围内使用void write_to_pipe(char* str)
{
write( fd[ 1 ], str, strlen( str ) );
}
:
fdopen()
答案 3 :(得分:0)
您正在关闭stdout文件描述符,该描述符会关闭管道。打开一次并保持它直到你完成。
答案 4 :(得分:0)
这个功能:
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()
不会终止char数组,因此代码必须这样做。并且数组必须比read()
语句中要求的最大字符数长1个字符。
注意: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
答案 5 :(得分:-1)
Duplicate描述符并在fdopen
调用中使用副本。