La raison la plus courante de ceci est que vous ne fermez pas l'extrémité d'écriture du tube, donc l'EOF n'est jamais envoyé. L'exemple commun est lorsque vous avez du code qui ressemble à:
int fds[2];
pipe(fds); // open a pipe
if (fork()) {
// parent process
write(fds[1], ... // write data
close(fds[1]); // close it
} else {
// child process
while (read(fds[0], ....) > 0) {
// read until EOF
Le problème ici est que la fin d'écriture du tube ne se ferme - le processus parent ferme, mais l'enfant a encore le descripteur d'écriture ouvert . Ainsi, l'enfant ne voit jamais un EOF sur le descripteur de lecture.
La première chose à faire après avoir forci l'enfant est de close(fds[1]);
, en fermant sa copie du descripteur d'écriture. De cette façon, lorsque le parent ferme la dernière référence à l'extrémité d'écriture du tube, l'enfant verra EOF à la fin de la lecture.
Modifier
regardant le lien que vous avez ajouté, c'est précisément le problème - l'enfant a toujours la fin d'écriture du tube ouvert sur son stdout. Ne pas dupliquer la fin d'écriture sur stdout chez l'enfant, fermez-le.Envoyer stdout ailleurs (un fichier journal, ou/dev/null)
Modifier
pour la communication bi-drectional, vous aurez besoin de deux tuyaux:
int tochild[2], fromchild[2];
pipe(tochild); pipe(fromchild);
if (fork()) {
close(tochild[0]);
close(fromchild[1]);
//write to tochild[1] and read from fromchild[0]
} else {
dup2(tochild[0], 0);
dup2(fromchild[1], 1);
close(tochild[0]); close(tochild[1]);
close(fromchild[0]); close(fromchild[1]);
exec(...
}
Vous devez être très Cependant, s'il y a beaucoup de données à envoyer à l'enfant, vous ne pouvez pas les envoyer avant de lire la sortie de l'enfant ou vous risquez de vous retrouver dans une impasse (les deux tuyaux se remplissent et les blocs parent essayer d'écrire plus de données pour l'enfant pendant que l'enfant bloque en essayant de sortir). Vous devez utiliser poll ou select pour indiquer quand il y a des données à lire ou écrire, et vous pouvez mettre les pipes (le parent se termine au moins) en mode non-bloquant.
Je mis à jour ma réponse. Et comme je pense à cette question, devrait-il avoir l'étiquette "devoirs"? Cela semble vraiment basique. –
Je vous assure que cela n'a rien à voir avec les devoirs. Je suis sorti de l'école depuis des années. Je ne suis pas un codeur c/C++ mais je construis un système de preuve de concept pour une démo que je fais et je suis revenu au code que je n'ai pas écrit comme dans plus de 10 ans. –