tags:

views:

45

answers:

3
void turtle (int gtot)
{
    int msg;
    fcntl(gtot,F_SETFL,O_NONBLOCK);
    read(gtot,&msg,4);

    gotoxy(12, 21); printf("The value of buffer for turtle is %d",msg);

    //react to god's message
    xcoor += msg;
    msg = 0;
            sleep(sleep_time);
 }

 void god (int gtot )
 {
        char choice, sign;
        int distance;
        scanf("%c",&choice);
        //choice = getchar();
        gotoxy(1,18);
        printf("Enter the distance which should be moved");
        fflush(stdout);
        gotoxy(50, 14);
        scanf ("%d", &distance);
        int newd = distance;
        //printf ("The distance that is to be moved by %d", distance);

        if (choice == 'h')
        {
            write(gtoh,&distance,4);
        }
        else if (choice == 't')
        {
            write(gtot,&newd,4);
            gotoxy(12,23);
                            printf("I am writing %d as the number", distance); 
                            fflush(stdout);
        }
        //printf("You chose %s", &choice);
        sleep(sleep_time);
    }
    main(){
int gtot[2];
pipe (gtot);
pid_turtle = fork ();
if (pid_turtle == 0)
  {
      close (gtot[1]);
      turtle (gtot[0]);
  }

pid_god = fork ();
if (pid_god == 0)
  {
      close (gtot[0]);
      god (gtot[1]);
  }
   }

When I write from the pipe from God function to the Turtle function. I expect it to return nothing when the user gives no input and the numbers when the user gives any. But the printf statement is printing outputs like

       The value of buffer for turtle is 0106368
       The value of buffer for turtle is 05291328

Which seems to me like the memory address of the number. What is the error that I am making in the program.

+1  A: 

If this is Linux try using strace to see the exact data being written to the pipes.

If this is Solaris or Mac OS X try dtrace or dtruss.

On BSD I believe the command to view system calls is just truss.

These are very useful commands.

Zan Lynx
Thanks a lot for the advice.
abhishekgupta92
+3  A: 

Several observations about your program:

In function turtle:

  1. You do not initialize the variable msg.
  2. You set the gtot file descriptor for O_NONBLOCK.
  3. BUT you do not check the return value of read.

This is a significant problem. read is returning immediately and you are printing the uninitialized value of msg.

  • The way you fork and close is also contributing. You have closed gtot[1] prior to fork-ing the "god" process. If you choose to use this one-parent of two-child-processes approach, don't close the file handles until you are done fork-ing.

  • Also, it appears that you intended for at least the turtle function, and probably the god function, to loop. As written, your turtle function will immediately exit: it has no loop and it performs read with the O_NONBLOCK flag set.

  • But wait, there is more. When you do call fcntl to set O_NONBLOCK, what you are doing is also resetting every flag other than O_NONBLOCK. Here is a function taken from the libc documentation which handles the other flags while setting or resetting the non-blocking flag:

/* Set the O_NONBLOCK flag of desc if value is nonzero, or clear the flag if value is 0. Return 0 on success, or -1 on error with errno set. */

int
set_nonblock_flag (int desc, int value)
{
  int oldflags = fcntl (desc, F_GETFL, 0);
  /* If reading the flags failed, return error indication now. */
  if (oldflags == -1)
    return -1;
  /* Set just the flag we want to set. */
  if (value != 0)
    oldflags |= O_NONBLOCK;
  else
    oldflags &= ~O_NONBLOCK;
  /* Store modified flag word in the descriptor. */
  return fcntl (desc, F_SETFL, oldflags);
}

There are some other things which could also be contributing to your problem:

  • It would be best to replace every occurence of "4" with sizeof(int) wherever you are calling read and write. It is possible that integers are 8 bytes on your machine (64 bit integer?), although pretty unlikely. In the future, it is more likely that int would be 8 bytes, and your code is very fragile in this regard.

There is also something "Strange" about your program that I am observing:

  • Why is the decimal output from printf being prefixed with a leading 0 (zero)? That would be an octal representation, but the printf specifier is not "%o". "%d" should not show leading zeros unless you use a width-specifier with a leading zero, a la "%08d". So I don't know what to make about that.
Heath Hunnicutt
Thanks, initializing the msg worked wonders !!!
abhishekgupta92
Glad to hear it. Namaste.
Heath Hunnicutt
And thanks again for other pieces of advices that you gave. They really helped my program and ofcourse me. :D
abhishekgupta92
+2  A: 

you dont want to call fork twice. You also dont want to close the unused ends of the pipe:)

I am supposed to call fork 4 times because of the nature of the programme it is a part of. But, why should I not close the unused ends of the pipe. I thought that is a good practice :)
abhishekgupta92