2017-05-30 89 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