在fclose()

时间:2017-05-30 11:23:26

标签: c unix

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;
}

6 个答案:

答案 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调用中使用副本。