2017-05-30 2 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); 

Wenn ich zuerst write_to_pipe aufrufen, dann funktioniert es vollkommen in Ordnung.Rohr "Schließen" nach fclose()

Wenn die Funktion zum zweiten Mal aufgerufen wird, schlägt fdopen fehl (gibt 0 zurück).

nahm ich an der Strom/Rohr/Somthing

Was der sichere Weg und rufen Sie die Funktion mehrmals

Compiler auf „das Rohr nicht schließen“ ist geschlossen ist: gcc 6.3.1


ps Diese Lesefunktion könnte auch ein ähnliches Problem haben.

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

Ihre 'read_from_pipe()' hat viel größeres Problem als die Deskriptordatei zu schließen. Du rufst 'read()' in 'FILE *'. Das wird überhaupt nicht funktionieren. 'read()' nimmt einen Dateideskriptor direkt und beendet das, was er liest, nicht. –

+0

Sie sollten einfach [popen (3)] (http://man7.org/linux/man-pages/man3/popen.3.html) mit 'pclose' verwenden –

+1

@BasileStarynkevitch Aber' popen() 'nicht eine bidirektionale Leitung bereitstellen. Es ist entweder schreibgeschützt oder schreibgeschützt. –

Antwort

1

Was der sichere Weg ist und rufen Sie die Funktion mehrmals

nicht fdopen() auf dem Dateideskriptor verwenden, um „das Rohr nicht schließen“:

void write_to_pipe(char* str) 
{ 
    write(fd[ 1 ], str, strlen(str)); 
} 

oder verwenden fdopen() im gleichen Umfang wie das Rohr selbst:

int fd[2]; 
. 
. 
. 
FILE *stream = fdopen(fd[ 1 ]); 
. 
. 
. 
void write_to_pipe(char* str) 
{ 
    fprintf(stream, "%s", str); 
} 
0

Sie schließen den Stdout-Dateideskriptor, der die Pipe schließt. Öffne es einmal und behalte es solange, bis du fertig bist.

-1

Duplicate der Deskriptor und verwenden Sie das Duplikat im fdopen Aufruf.

1

Sie könnten dup den Dateideskriptor und führen Sie die fdopen auf das Duplikat.

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

In jedem Fall sollte Ihre Funktion wahrscheinlich eine ganze Zahl zurückgeben, um mögliche Fehler innerhalb der Funktion anzuzeigen.

2

Standard C kennt keine POSIX-Dateideskriptoren, nur FILE * ist Standard, und fclose() schließt die Datei. Dies bedeutet natürlich, dass alles getan wird, was auf der Plattform notwendig ist, um die Datei zu schließen, so dass in diesem Fall close() auf dem zugrunde liegenden Deskriptor aufgerufen wird.

Was Sie tun sollten, verwenden Sie einfach FILE *, wo immer es angebracht ist. Wenn Sie also eine Pipe als Backend für Ihre FILE *, fdopen() Datei direkt nach dem Erstellen der Pipe benötigen. Auf diese Weise haben Sie Ihren plattformspezifischen Code an einem einzigen Ort.

Wenn Sie den Dateideskriptor für etwas anderes als Schließen der Pipe benötigen, können Sie fileno() auf der FILE * verwenden, aber dann haben Sie einen anderen plattformabhängigen Teil in Ihrem Code.

0

diese Funktion:

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

mehrere Probleme enthält.

vorschlägt es ähnlich wie das Schreiben:

#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 

Hinweis: read() beendet nicht den char-Array, so dass der Code, das zu tun hat, und das Array 1 Zeichen länger als die maximale Anzahl von Zeichen fragen für in der read() Aussage.

Hinweis: Die Syntax für read() möchte einen int, nicht FILE* für seinen ersten Parameter. Hier ist die richtige Syntax:

ssize_t read(int fd, void *buf, size_t count); 

diese Funktion:

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

lässt viel zu wünschen übrig.

vorschlagen etwas ähnliches wie:

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