Reputation: 2813
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.
Upvotes: 1
Views: 2479
Reputation: 19467
Several observations about your program:
In function turtle
:
msg
.gtot
file descriptor for O_NONBLOCK
.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:
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:
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.Upvotes: 3
Reputation: 485
you dont want to call fork twice. You also dont want to close the unused ends of the pipe:)
Upvotes: 2
Reputation: 54393
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.
Upvotes: 1