Classic C. Mit Rohren in execvp Funktion, stdin und stdout Umleitung
Möchte ich simulieren bash auf meinem Linux-C-Programm durch Rohre und execvp Funktion. e.g
ls -l | wc -l
Dort ist mein Programm:
if(pipe(des_p) == -1) {perror("Failed to create pipe");}
if(fork() == 0) { //first fork
close(1); //closing stdout
dup(des_p[1]); //replacing stdout with pipe write
close(des_p[0]); //closing pipe read
close(des_p[1]); //closing pipe write
if(execvp(bash_args[0], bash_args)) //contains ls -l
/* error checking */
}
else {
if(fork() == 0) { //creating 2nd child
close(0); //closing stdin
dup(des_p[0]); //replacing stdin with pipe read
close(des_p[1]); //closing pipe write
close(des_p[0]); //closing pipe read
if(execvp(bash_args[another_place], bash_args)) //contains wc -l
/* error checking */
}
close(des_p[0]);
close(des_p[1]);
wait(0);
wait(0);
}
Dieser code tatsächlich ausgeführt wird, aber nicht das richtige.
Was ist falsch an diesem code? Das funktioniert nicht und ich habe keine Ahnung, warum.
InformationsquelleAutor krzakov | 2012-12-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie schließen Sie das pipe-fds-in der Eltern, oder das Kind nicht erhalten, EOF, weil das Rohr ist immer noch offen für das schreiben in die Muttergesellschaft. Dies würde bewirken, dass die zweite
wait()
zu hängen. Für mich funktioniert:Es ist eine ziemlich zuverlässige Faustregel: Wenn Sie
dup()
oderdup2()
duplizieren Sie das eine Ende des Rohres, um die Standardeingabe oder Standardausgabe, müssen Sieclose()
beiden enden der original-Rohr. könnte Es Umstände geben, wo dies nicht der notwendige Verhalten, aber solche Umstände sind sehr selten anzutreffen ist.Wollte nur darauf hinweisen, dass, wenn Sie mehrere
execvp
Anrufe, die kommunizieren miteinander über pipes, nur in der Nähe von schreiben der Rohre in den übergeordneten (und schließen in Kind). Wenn Sie in der Nähe sowohl in der Eltern, nachfolgende Aufrufewaitpid
hängen.Denken Sie Herunterfahren, nicht in der Nähe? Bei der Gabelung ein Kind, Sie wollen, zu schließen, alle fd, die das Kind verwenden.
solltest du wirklich post eine neue Frage gestellt, da Sie tatsächlich um Hilfe bittet, Ihren code Debuggen! Sie tun müssen, schließen Sie alle fd, die das Kind nutzt, dein code hat ein anderes problem. In die auskommentierte Zeile, die Sie sind, schließen ein fd, welches die nächste iteration der Schleife wäre mit! Sie sollte in der Nähe alle die fds in den Eltern - nur nicht, bis Sie fertig sind mit Ihnen in den übergeordneten. Wenn Sie überprüft hatte, den Rückgabewert dup2 Sie würden bemerkt haben (Sie müssen auch prüfen, den return-codes von Rohr/Gabel/schließen/execvp/waitpid).
InformationsquelleAutor Nicholas Wilson
Lesen, auf was die
wait
Funktion hat. Es wird warten, bis ein Kind-Prozess vorhanden ist. Warten Sie für das erste Kind beenden, bevor Sie beginnen das zweite Kind. Das erste Kind wird wahrscheinlich nicht verlassen, bis es ein gewisser Prozess, liest aus der anderen Ende der Leitung.Erstellen von Prozessen mit dem Rohr zwischen dann, dann
wait
zweimal für beide von Ihnen zu beenden.Ist es so schwer, mir zu zeigen, Beispiel in meinem code?
Für die Akten, der Fall nicht gelöst wird noch.
Sie brauchen zum schließen der pipe-fds-in der Eltern, oder das zweite Kind nicht erhalten EOF, und so hängen (es sei denn, das erste Kind ist sehr scharf und fordert
shutdown()
am Ende).InformationsquelleAutor Art