2017-05-30 49 views
0
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; 
} 
+2

你'read_from_pipe()'有很多比关闭文件描述符更大的问题。你在'FILE *'中调用'read()'。这根本不起作用。 'read()'直接获取一个文件描述符,并且它不会NUL终止它所读取的内容。 –

+0

你应该使用[popen(3)](http://man7.org/linux/man-pages/man3/popen.3.html)和'pclose' –

+1

@BasileStarynkevitch但是'popen()'不会提供一个双向管道。它是只读或只写的。 –

回答

1

什么是安全的方式,以“不关闭管道”和调用函数多次

不要在文件描述符使用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); 
} 
0

您正在关闭关闭管道的stdout文件描述符。打开它一次,并保持它,直到你完成。

-1

Duplicate描述符并使用fdopen调用中的副本。

1

您可能dup的文件描述符并在复制上执行fdopen

int write_to_pipe(char* str) 
{ 
    int file = dup(fd[1]); 
    if(0>file) 
     return -1; 
    FILE *stream; 
    //... 
} 

在任何情况下,您的函数应该可能返回一个整数,以便它可以表示函数内可能发生的可能错误。

2

标准C不知道POSIX文件描述符,只有FILE *是标准的,fclose()关闭文件。这当然意味着在平台上做任何必要的操作来关闭文件,所以在这种情况下,在底层描述符上调用close()

你应该做的只是在适当的地方使用FILE *。因此,如果在创建管道后立即需要管道作为您的FILE *fdopen()的后端。这样,您就可以在一个地方使用特定于平台的代码。

如果您碰巧需要文件描述符来关闭管道以外的任何其他功能,可以在FILE *上使用fileno(),但在代码中有另一个与平台相关的部件。

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()不会终止字符数组,所以代码必须做到这一点,数组必须是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