Reputation: 1212
I have a program where two child processes are created belonging to the same father. Now the program starts by hitting control C and then works by pressing control Z each time.
Aim is for child 1 to write two numbers to child 2 and child two divides the numbers and writes the result back to child 1 that displays it. As a result two pipes are needed (fd and sd).
I got the first pipe working fine, so the numbers are sending over...in child 2(for debugging) it displays the correct number so if it had 8 and 2....the right answer of 4 is displayed in child 2. Now I can't seem to get this "4" or whatever the result is back to child 1.
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
void handleSignal(int sig)
{
if (sig == SIGTSTP)
{
return;
}
}
int main()
{
int fd[2];
int sd[2];
int pipe1 = 0;
int pipe2 = 0;
pid_t fork1 = 0;
pid_t fork2 = 0;
int num1, num2, result;
int myJump = 0;
int returnResult = 99;
signal(SIGINT, handleSignal);
printf("Waiting for interrupt\n");
pause();
signal(SIGINT, SIG_IGN);
pipe1 = pipe(fd);
pipe2 = pipe(sd);
//pipe checks been omitted...for simplicity
fork1 = fork();
//fork check been omited..for simplicity
signal(SIGTSTP, handleSignal); //wait till control Z is pressed
if (fork1 == 0)
{
dup2(fd[1], 1);
dup2(sd[0], 0);
close(fd[0]);
close(sd[1]);
while(1)
{
pause();
int randNum1 = rand() % 9 + 1;
fprintf(stderr, "Child 1: %d\n", randNum1);
printf("%d\n", randNum1);
fflush(stdout);
scanf("%d", &returnResult);
fprintf(stderr, "result in A :%d \n", returnResult);
}
}
else if (fork1 > 0)
{
fork2 = fork();
if (fork2 == 0)
{
signal(SIGTSTP, handleSignal);
dup2(fd[0], 0);
dup2(sd[1], 1);
close(fd[1]);
close(sd[0]);
if (myJump == 0)
{
pause();
scanf("%d", &num1);
printf("CHild 2: %d\n", num1);
myJump = 1;
}
if (myJump == 1)
{
while (1)
{
pause();
scanf("%d", &num2);
result = num2 / num1;
fprintf(stderr, "result from B: %d \n", result);
num1 = num2;
printf("%d \n", result);
}
}
}
else
{
wait();
}
}
else
{
printf("errror \n");
}
return 0;
}
If anyone could see whats wrong, if you was to run it...it works by hitting control C first then you have to keep hitting control Z. You can then see that the result from child A doesn't match that of B as shown below
Waiting for interrupt
^C^ZChild 1: 2
result in A :99
^ZChild 1: 8
result in A :99
result from B: 4
^ZChild 1: 1
result in A :99
result from B: 0
Upvotes: 1
Views: 363
Reputation: 9385
The pipes are actually working fine... it's scanf()
that's failing. When your second child process starts, it calls:
if (myJump == 0)
{
pause();
scanf("%d", &num1);
printf("CHild 2: %d\n", num1); /* <== problem here */
myJump = 1;
}
...and the printf()
there leaves "CHild 2: " as the next data in the sd[]
pipe. Because of that, when your first child process calls scanf()
to read the result from the second, scanf()
fails and leaves returnResult
unchanged. Since scanf()
failed, the data is left on the stream, and future attempts to scanf()
the result fail the same way.
How to fix it depends on what you want. If you want your second child process to just return the number it read as the result for the first pass, then just modify the offending printf()
to write just the number without the text:
if (myJump == 0)
{
pause();
scanf("%d", &num1);
printf("%d\n", num1); /* <== Changed: number only, no text */
myJump = 1;
}
I should add that although the change mentioned above will fix the problem, you should generally check the return from scanf()
to see whether it succeeds and take appropriate action if it doesn't.
Upvotes: 2