int main()
{
int pipefd[2];
char buf;
int pid, pid1;
pid = fork();
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
if(pid == 0){ // CHILD 1
close(pipefd[1]);
while(read(pipefd[0],&buf,1) > 0){ // THIS DOESNT WORK
printf("FIRST CHILD WRITES: %s\n",&buf); // THIS DOESNT WORK
} // THIS DOESNT WORK
close(pipefd[0]);
_exit(EXIT_SUCCESS);
}else{
pid1 = fork();
if(pid1 == 0){ // CHILD 2
close(pipefd[1]);
// while(read(pipefd[0],&buf,1) > 0){ // ONLY THIS (WOULD) WORK
// printf("SECOND CHILD WRITES: %s\n",&buf); // ONLY THIS (WOULD) WORK
// } // ONLY THIS (WOULD) WORK
close(pipefd[0]);
_exit(EXIT_SUCCESS);
}else{ // PARENT
close(pipefd[0]);
char* s = "Write To Pipe";
write(pipefd[1],s,strlen(s));
close(pipefd[1]);
wait(NULL); // WAIT FOR CHILD TO TERMINATE
wait(NULL); // WAIT FOR CHILD TO TERMINATE
}
}
return 0;
}
Whenever I try to run the program only the 2ND CHILD can read from the pipe, the 1ST CHILD never. So I tried commenting the second child's pipe reading, however the first child still can't read from the pipe to which the parent wrote into.
Why can't the 1ST CHILD read from the pipe?
Thanks for the help!
The order is wrong. Your code is
pid = fork();
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
You need to create the pipe before you fork. You would probably catch this type of error if you check for errors on the close and/or the read.
Related
How can i send signal from parent process to the child?
After i write to the pipe i want to send signal to the child process.
pid_t pid;
int filds[2];
pipe(filds);
char *args[150] = {"./draw.out", NULL};
char buff = '\0';
if ((pid = fork()) < 0) { // fork a child process/
printf("*** ERROR: forking child process failed\n");
exit(1);
} else if (pid == 0) {
execvp(args[0], args); // execute the command
} else { // for the parent
char btnPressed = getch();
while (btnPressed != 'q'){
btnPressed = getch();
write(filds[1],buff, BUFF_SIZE);
//signal
}
// signal finish game.
}
kill(PID, SIGwhatever);
however this is probably a poor choice; the better solution is
close(filds[1]);
and handle close of input in the child. I think you're missing a
dup2(files[0],0);
in the child path as well.
I am trying to learn programming on and I don’t understand why I can't get child 2 to print hello. I have also closed both read and write ends of the pipe for the parent because I don’t want the parent to communicate. Any help is much appreciated.
int main ()
{
int fd[2];
pid_t child_pid, child_pid1;
if (pipe(fd) < 0)
{
printf("Pipe error");
}
child_pid = fork (); // child 1
if (child_pid != 0)
{
printf("im child 1");
dup2 (fd[1], STDIN_FILENO);
printf("greetings");
child_pid1 = fork (); //child 2
if (child_pid1 != 0)
{
printf("im child 2");
dup2(fd[0], STDOUT_FILENO);
printf("hello");
}
else if (child_pid1 > 0) //Parent Code
{
close (fd[0]);
close (fd[1]);
}
}
return 0;
}
Your first if clause is wrong.
child_pid = fork (); // child 1
if (child_pid != 0)
{
printf("im child 1");
}
This is not the child but the parent. If it is the child, then pid will be 0, only on the parent you have child_pid != 0.
The same happens in the second if clause as well.
You should do if(child_pid == 0) in both cases, if you want that code to be executed in the child process.
In this function, how do I make it so that the parent stops trying to read from the pipe. I.e. if I run the command ls | grep test grep won't output test and test.c and then wait for user input?
pipe(pipefd);
int pid = fork();
if (pid != 0) {
dup2(pipefd[0], STDIN_FILENO);
int rv2 = execv(get_contain_dir(command_to), args_to);
close(pipefd[0]);
} else {
dup2(pipefd[1], STDOUT_FILENO);
int rv1 = execv(get_contain_dir(command_from), args_from);
close(pipefd[1]);
}
You are not closing the pipes correctly. Each process must close the pipe that it does not use :
int pid = fork();
if (pid != 0) {
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[1]); // not using the left side
int rv2 = execv(get_contain_dir(command_to), args_to);
} else {
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[0]); // not using the right side
int rv1 = execv(get_contain_dir(command_from), args_from);
}
Is there a nice way to send a SIGUSR to a grandchild directly?
E.g. I have some process tree:
0
/ \
1 2
\
3
and need to send a signal from 0 to 3.
I know I could save child's pid after forking and the use it with kill() like
pid = fork();
if (pid == 0) {
pid = fork();
if (pid == 0) { /* grandchild */ }
savepid = pid;
}
...
kill(savepid,sig);
but then I'd have to use shared memory to make those variable globally visible, which is not allowed in my homework :)
There is no direct communication between parent and grandchildren. The usual approach here is having the grandchild to store its PID somewhere on the filesystem (say, in /var/lib/myapp/grandchild.pid) and reading it back in the parent.
You can also use process groups on Linux, but they offer a coarse-grained approach.
dunno if this works flawlessly, but the MAIN idea is here
int fd[2]; /*write(fd[1],buffer,strlen)
/ read(fd[0],buffer2,SIZE)*/
pid_t cpid,savepid;
if(pipe(fd)==-1){
perror("pipe");
exit(EXIT_FAILURE);
}
if((cpid=fork())<0){/* FORK INIT FOR CHILD */
printf("\n\tFORK ERROR\n");
exit(1);
}
if(cpid==0){ /*process CHILD*/
if((cpid=fork())<0){/* FORK INIT FOR GRANDCHILD */
printf("\n\tFORK ERROR\n");
exit(1);
}
if(cpid==0){ /*process GRANDCHILD*/
close(fd[0]);
if((write(fd[1],(char*)pid,strlen(final2)))<0){
perror("\n\tWRITE ERROR");
}
/********CODE******/
close(fd[1]);
}else{ /*process CHILD*/
/********CODE******/
}
}else{ /*process PARENT*/
close(fd[1]);
if((read(fd[0],(char*)savepid,NN))<0){
perror("\n\tREAD ERROR");
}
/********CODE******/
kill(savepid,SIGKILL);
/*code parent*/
wait(NULL);
close(fd[0]);
}
Learning to use the fork() command and how to pipe data between a parent and it's children. I am currently trying to write a simple program to test how the fork and pipe functions work. My problem seems to be the correct use/placement of the wait function. I want the parent to wait for both of its children to finish processing. Here is the code I have so far:
int main(void)
{
int n, fd1[2], fd2[2];
pid_t pid;
char line[100];
if (pipe(fd1) < 0 || pipe(fd2) < 0)
{
printf("Pipe error\n");
return 1;
}
// create the first child
pid = fork();
if (pid < 0)
printf("Fork Error\n");
else if (pid == 0) // child segment
{
close(fd1[1]); // close write end
read(fd1[0], line, 17); // read from pipe
printf("Child reads the message: %s", line);
return 0;
}
else // parent segment
{
close(fd1[0]); // close read end
write(fd1[1], "\nHello 1st World\n", 17); // write to pipe
// fork a second child
pid = fork();
if (pid < 0 )
printf("Fork Error\n");
else if (pid == 0) // child gets return value 0 and executes this block
// this code is processed by the child process only
{
close(fd2[1]); // close write end
read(fd2[0], line, 17); // read from pipe
printf("\nChild reads the message: %s", line);
}
else
{
close(fd2[0]); // close read end
write(fd2[1], "\nHello 2nd World\n", 17); // write to pipe
if (wait(0) != pid)
printf("Wait error\n");
}
if (wait(0) != pid)
printf("Wait error\n");
}
// code executed by both parent and child
return 0;
} // end main
Currently my output looks something along the lines of:
./fork2
Child reads the message: Hello 1st World
Wait error
Child reads the message: Hello 2nd World
Wait error
Where is the appropriate place to make the parent wait?
Thanks,
Tomek
That seems mostly ok (I didn't run it, mind you). Your logic error is in assuming that the children will end in some particular order; don't check the results of wait(0) against a particular pid unless you're sure you know which one you're going to get back!
Edit:
I ran your program; you do have at least one bug, your second child process calls wait(), which you probably didn't want to do. I recommend breaking some of your code out into functions, so you can more clearly see the order of operations you're performing without all the clutter.
i think its better to use something like this, in order to wait for all the childrens.
int stat;
while (wait(&stat) > 0)
{}