2012-03-27 3 views
1

Ich schrieb diese Funktion für die Kommunikation mit einem externen Programm. Ein solches Programm nimmt Eingaben von stdin und druckt seine Ausgabe auf stdout. Um meinen Code mit diesem Programm kommunizieren zu lassen, leite ich die stdin und stdout zu den Puffern um, die Pfeifen verwenden.C pipe() gibt Fehler nach einer bestimmten Anzahl von Aufrufen zurück

das Problem ist, dass das 204. Mal, dass ich diese Funktion aufrufen, Pipe() gibt mir einen Fehler (-1) zurück! Irgendeine Idee warum ist das, oder wie kann ich es vermeiden? vielen Dank

weitere Details: Dies ist unter Linux. Das Ergebnis von uname -a lautet:

Linux snowy.*****.ac.uk 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux 
+2

Was ist der Wert oder 'errno' zum Zeitpunkt des Fehlers? – trojanfoe

+1

'man 3 errno',' ulimit -n' und überprüfen Sie, wie viele offene Dateideskriptoren Sie in diesem Prozess haben. –

+2

Besser noch, was ist der Wert von 'strerror (errno)'? –

Antwort

0

Wie viele von Ihnen vorgeschlagen haben, war das Problem, dass ich es versäumt habe, die Dateideskriptoren zu schließen, bevor ich von der Funktion zurückkehrte, so dass ich bald keine verfügbaren mehr hatte.

Hier folgt die überarbeitete (Arbeits-) Version des Codes

int query_oracle(mpz * c,int *t, mpz * m) { 
    int out_pipe[2]; 
    int in_pipe[2]; 
    int saved_stdout; 
    int saved_stdin; 

    // REDIRECT STDIN 
    saved_stdin = dup(STDIN_FILENO);  /* save stdin for later */ 
    pipe(in_pipe);   /* make a pipe */ 
    close(STDIN_FILENO); 
    dup2(in_pipe[0], STDIN_FILENO); /* redirect pipe to stdin */ 
    //write(in_pipe[1], in_buf, strlen(in_buf)); 

    // REDIRECT STDOUT 
    saved_stdout = dup(STDOUT_FILENO); /* save stdout for display later */ 
    if(pipe(out_pipe) != 0) {   /* make a pipe */ 
    exit(1); 
    } 
    dup2(out_pipe[1], STDOUT_FILENO); /* redirect stdout to the pipe */ 
    close(out_pipe[1]); 

    /* Some reads and writes on the pipes occur here 
    * so that the program can communicate with an 
    * external program*/ 

    dup2(saved_stdout, STDOUT_FILENO); /* reconnect stdout */ 
    dup2(saved_stdin, STDIN_FILENO); /* reconnect stdin */ 

    /* close all open file descriptors */ 
    close(in_pipe[1]); 
    close(in_pipe[0]); 
    close(out_pipe[1]); 
    close(out_pipe[0]); 
    close(saved_stdin); 
    close(saved_stdout); 

    return 0; 
} 
6

Sie führen möglicherweise unsere Dateideskriptoren aus. Es sieht so aus, als ob du in_pipe [1] und out_pipe [0] im Programm nicht schließt, nachdem du das Remote-Programm gegabelt hast, oder überhaupt.

+1

Und 'saved_stdout' und' saved_stdin' machen 4 * 204 ~ = 1024 (das wahrscheinliche fd-Limit). – trojanfoe

+1

Dies würde "EMFILE" ergeben, aber das OP scheint "EPERM" zu bekommen. –

+0

@larsmans Ich glaube nicht, dass er ist. Ich würde gerne den überarbeiteten Code sehen. – trojanfoe