Да, когато форкнеш нов процес, той унаследява файловите дескриптори на родителският процес. Обаче след това ако примерно отвориш нов или създадеш pipe в родителският процес, child-a не би трябвало да има идея за това.
Та пробва ли да размениш тези два реда:
pid1=fork();
pipe(fd);
----------------------------
FUCKING SHIT!!!
Сега хвърлих едно око на кода, какво си направил бе човек?!?
Няма да стане така.
Първо, няма да стане само с един pipe по този начин по който го правиш, трябва да създадеш 5 отделни pipes, всеки от тях преди съответните fork() функции. Защо това? Защото затваряш единия край където се пише и след това се опитваш да пишеш там, нормално е да се случи случка и нищо да не се изпише:
...
else
{
wait();
[b] close(fd[1]);[/b]
if(read(fd[0],&i,sizeof(i))==-1)
{
perror("Read ID5");
}
buf[4]=i;
printf("proc5 ID %d\n",i);
close(fd[0]);
int id4=getpid();
[b] write(fd[1],&id4,sizeof(id4));[/b]
close(fd[1]);
printf("proc4 ID sent\n");
}
Но дори да разрешиш този проблем с писането във вече затворен дескриптор, пак ще има проблеми с цялата тарапана. Pipes ще сработят между процес-родител и child process, но не мисля, че ще сработят през серия от forks, с други думи не съм убеден, че можеш да правиш pipe();fork();fork(); и процесът...ъъъъм *внук* да може да пише и чете във pipe-a създаден от *баба му*.
Другото което е, не можеш да пазиш тези неща в глобалната променлива buf. Това са процеси, а не нишки, процесите си имат собствени адресни пространства. Ако в рамките на един child промениш buf[], то в рамките на процеса-родител въобще няма да се отрази тази промяна. Което прави последният цикъл да изпишеш стойностите на buf[] безсмислен. За целта пробвай някакъв IPC механизъм, но не и по този начин.
От wait() файда нямаш никаква, защото четенето от pipe-a е блокираща операция: докато не се подаде нещо от другия край, тя няма да завърши. Така че ти е гарантирано че ще си прочетеш стойността СЛЕД като процесът-дете ти я изпише. Особено при положение че четеш и пишеш там една 4-байтова стойност, да беше повече можеше да се появят проблеми предполагам и тогава да се налага да се изчаква детето да умре (пак лоша стратегия, но това е друга бира).
Както и да е, така ще сработи:
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int fd[2];
int fd1[2];
int fd2[2];
int fd3[2];
int fd4[2];
main()
{
int i,pid1,pid2,pid3,pid4,pid5;
pipe(fd);
pid1=fork();
if(pid1==0)
{
pipe(fd4);
pid2=fork();
if(pid2==0)
{
pipe(fd3);
pid3=fork();
if(pid3==0)
{
pipe(fd2);
pid4=fork();
if(pid4==0)
{
pipe(fd1);
pid5=fork();
if(pid5==0)
{
int id5;
id5=getpid();
close(fd1[0]);
write(fd1[1],&id5,sizeof(id5));
close(fd1[1]);
printf("proc5 ID sent \n");
}
else
{
close(fd1[1]);
if(read(fd1[0],&i,sizeof(i))==-1)
{
perror("Read ID5");
}
printf("proc5 ID %d\n",i);
close(fd[0]);
int id4=getpid();
write(fd2[1],&id4,sizeof(id4));
close(fd2[1]);
printf("proc4 ID sent\n");
}
}
else
{
close(fd2[1]);
if(read(fd2[0],&i,sizeof(i))==-1)
{
perror("Read ID4");
}
printf("proc4 ID %d\n",i);
close(fd1[0]);
int id3=getpid();
write(fd3[1],&id3,sizeof(id3));
close(fd3[1]);
printf("proc3 ID sent\n");
}
}
else
{
close(fd3[1]);
if(read(fd3[0],&i,sizeof(i))==-1)
{
perror("Read ID3");
}
printf("proc3 ID %d\n",i);
close(fd[0]);
int id2=getpid();
write(fd4[1],&id2,sizeof(id2));
close(fd4[1]);
printf("proc2 ID sent\n");
}
}
else
{
close(fd4[1]);
if(read(fd4[0],&i,sizeof(i))==-1)
{
perror("Read ID2");
}
printf("proc2 ID %d\n",i);
close(fd4[0]);
int id1=getpid();
write(fd[1],&id1,sizeof(id1));
close(fd[1]);
printf("proc1 ID sent\n");
}
}
else
{
close(fd[1]);
if(read(fd[0],&i,sizeof(i))==-1)
{
perror("Read ID1");
}
printf("proc1 ID %d\n",i);
close(fd[0]);
}
}