Reputation: 182
I need help with this sample application. When I run it, it gets stuck after the child process prints "Child sending!".
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#define INPUT 0
#define OUTPUT 1
int main()
{
int fd1[2];
int fd2[2];
int pid;
if (pipe(fd1) < 0)
exit(1);
if (pipe(fd2) < 0)
exit(1);
if ((pid = fork()) < 0)
{
perror("fork");
exit(1);
}
else if (pid == 0)
{
close(fd1[INPUT]);
close(fd2[OUTPUT]);
char *str = "Hello World!";
printf("Child sending!\n");
write(fd1[OUTPUT], str, strlen(str));
char *bufferc = (char *)malloc(1000);
char *readbufferc = (char *)malloc(80);
int rdc;
int gotdata = 0;
while (gotdata == 0)
while ((rdc = read(fd2[INPUT], readbufferc, sizeof(readbufferc))) > 0)
{
strncat(bufferc,readbufferc,rdc);
gotdata = 1;
}
printf("Child received: %s",bufferc);
free(readbufferc);
free(bufferc);
exit(0);
}
else
{
close(fd1[OUTPUT]);
close(fd2[INPUT]);
int rd;
char *buffer = (char *)malloc(1000);
char *readbuffer = (char *)malloc(80);
int gd = 0;
while (gd == 0)
while ((rd = read(fd1[INPUT],readbuffer, sizeof(readbuffer))) > 0)
{
strncat(buffer, readbuffer,rd);
gd = 1;
}
printf("Parent received: %s\n",buffer);
free(readbuffer);
printf("Parent sending!");
write(fd2[OUTPUT], buffer, strlen(buffer));
free(buffer);
}
return 0;
}
On a side note, is there a way to debug when I use fork, because GDB automatically goes to the parent process?
Upvotes: 1
Views: 2446
Reputation: 9279
You are calling read()
in the expectation that if there is nothing to read, it will return with zero bytes read. However, what you are seeing is because read()
is waiting for some data before returning. To address this, you need to do one of two things:
select()
or poll()
to see whether there is some data to read before you read itAlso, several other points:
malloc()
malloc()
does not return NULL
gotdata
thing with a break
instructionUpvotes: 0
Reputation: 7054
There are many bugs in your code. Why are you using fd2 without initializing it? Remove it.
Now it's stuck at "Child sending", because pipe read is a blocking call and you are putting it in a while loop which will never return. Please refer to the man page of pipe.
If you want to break that while loop, close all write ends of that pipe.
Also to debug a child process, use the GDB command follow-fork-mode
as child before call to fork() while debugging.
Upvotes: 1
Reputation: 2170
Several things wrong:
fd2
is just never initialized.
The parent will never exit this:
while ((rd = read(fd1[INPUT],readbuffer, sizeof(readbuffer))) > 0)
{
strncat(buffer, readbuffer,rd);
gd = 1;
}
If there is no data to read, read will block and just not return. The only thing that would make it exit is if the connection was closed and the child doesn't close it.
Upvotes: 1
Reputation: 755010
After the child writes to the parent, it must close the write end of the pipe so the parent knows it has reached EOF.
Upvotes: 5