2017-12-11 3 views
0

Ich versuche, die Antwort eines Char-Ausdruck mit bc durch Rohre zu bekommen. Ich möchte zuerst den Ausdruck in der Pipe1 schreiben, die die BC liest und die Antwort in Pipe2 schreiben. Dazu verändere ich die Ein- und Ausgabe. Das funktioniert, wenn ich [] kein Zeichen verwenden und einfach den Ausdruck in der Schreib:Verwenden von BC durch Rohre und Gabel

write(pipe1[1], "20*5\n", sizeof("20*5\n")-1) != sizeof("20*5\n")-1) 

Aber wenn ich eine Registerkarte erklären, halte ich den Fehler bekommen:

(standard_in) 2: illegal character: ^@ 

Manchmal es ist 1 statt 2

Was mache ich falsch? Wenn mir jemand erklären könnte, danke.

Code:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main(void) 
{ 
    char resultat[5]; 
    int pipe1[2]; 
    int pipe2[2]; 

    pipe(pipe1); 
    pipe(pipe2); 

    int resultat_fork = fork(); 

    if (resultat_fork == -1) 
    { 
     exit(EXIT_FAILURE); 
    } 

    char* expression = "20*5\n"; 

    if (resultat_fork != 0) 
    { 
     //printf("I am the parent\n"); 

     close(pipe1[0]); 
     close(pipe2[1]); 

     if (write(pipe1[1], expression, sizeof(expression)) != sizeof(expression)) 
      fprintf(stderr, "write to child failed\n"); 

     int nbytes = read(pipe2[0], resultat, sizeof(resultat)); 
     if (nbytes <= 0) 
      fprintf(stderr, "read from child failed\n"); 
     else 
      printf("resultat: %.*s\n", nbytes, resultat); 

     close(pipe1[1]); 
     close(pipe2[0]); 
    } 
    else 
    { 
     printf("I am the child\n"); 

     close(pipe1[1]); 
     close(pipe2[0]); 
     dup2(pipe1[0], 0); 
     dup2(pipe2[1], 1); 
     close(pipe1[0]); /* More closes! */ 
     close(pipe2[1]); /* More closes! */ 

     execlp("bc", "bc", NULL); 
     fprintf(stderr, "Failed to execute bc\n"); 
     exit(EXIT_FAILURE); 
    } 
    return 0; 
} 
+0

Die Variable Ausdruck ist ein Zeiger, kein Array. Verwenden Sie 'strlen()' anstelle von 'sizeof'. (Ich habe erwähnt, dass ich 'strlen()' im Kommentar zu meiner vorherigen Antwort auf eine frühere Variante dieser Frage verwende.) –

+0

Okay, bitte akzeptiere meine Entschuldigung, ich habe es im Moment nicht wirklich verstanden. – Karl

+0

Entschuldigung akzeptiert - es kann schwierig sein, die Nuggets nützlicher Informationen im Detritus des Kommentars zu erkennen (sowohl innerhalb als auch nach einer Antwort). –

Antwort

1

^@ ist das NUL-Zeichen heißt '\0'. Dies würde darauf hindeuten, dass Sie das Ende der Zeichenfolge überschreiben, wenn Sie es in bc schreiben. Das Problem ist hier:

sizeof(expression) 

expression kein Array ist, es ist ein char Zeiger, der auf das erste Zeichen des Strings Punkte "20*5\n", und wenn Sie auf einem 64-Bit-Computer sind, ist seine Größe 8. Holen Sie sich die Länge der zu sendenden Zeichenfolge, verwenden Sie stattdessen strlen(expression).

Eine andere Sache, die Sie tun müssen, nicht mit Ihrem Problem verbunden ist, im übergeordneten Prozess, nachdem Sie die Antwort wait für den untergeordneten Prozess zu Ende gelesen haben. Sonst bleibt dir ein Zombie.

+0

Vielen Dank für die Beantwortung, ich werde versuchen, zu verwenden. – Karl

+0

Beachten Sie, dass ein Systemprozess (normalerweise PID 1, "init") das verwaiste Kind erbt und keinen Zombie erstellt, wenn das Elternelement beendet wird, bevor das Kind es tut. Das einzige Mal, wenn Sie einen Zombie erhalten, ist, dass der Elternprozess erst nach dem Beenden des Kindes beendet wird, aber der Elternprozess nicht zu irgendeinem Zeitpunkt auf das Kind wartet.Dies wird zu einem Problem, wenn der Elternteil viele Zombies erzeugt; ein Zombie ist selten ein Problem, und viele Prozesse verlassen ziemlich schnell, so dass die Möchtegern-Zombies automatisch vom System aufgeräumt werden. –

1

Das ist falsch

if (write(pipe1[1], expression, sizeof(expression)) != sizeof(expression)) 

Sie verwenden sizeof Operator mit expression die eine char* ist, wenn Ihr System 32-Bit ist, ist es in 4 führen wird, die die Größe einer Zeigervariable ist in Ihrem Code.

Sie müssen strlen(expression) anstelle von sizeof verwenden.

Wie bereits in der Antwort erwähnt, müssen Sie darauf warten, dass der untergeordnete Prozess seine Ausführung beendet und beendet wird, wenn der übergeordnete Prozess mehrere untergeordnete Prozesse aufweist. Im Idealfall sollten Sie auch den Rückgabewert wait überprüfen, der Ihnen mehr Kontext für die Beendigung des untergeordneten Prozesses bietet.

+0

Okay, ich werde das auch versuchen, danke für die Hilfe, sehr nützlich. – Karl