tags:

views:

251

answers:

4

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

+1  A: 

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.

246tNt
+1  A: 

There are many bugs in your code. Why are you using fd2 without initializing it? Remove it. Now its 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 man page of pipe.
If you want to break that while loop, close all write ends of that pipe.

Also to debug child process, use gdb command follow-fork-mode as child before call to fork() while debugging.

vinit dhatrak
thanks for the follow-fork-mode command. will definitely come in handy
reubensammut
A: 

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:

  • set your socket to do non-blocking reads (not recommended)
  • use select() or poll() to see whether there is some data to read before you read it

Also, several other points:

Tim
A: 

After the child writes to the parent, it must close the write end of the pipe so the parent knows it has reached EOF.

Jonathan Leffler
Thanks a lot I really appreciate it!
reubensammut