Reputation: 35
I am writing a code in which children and parent should give time information to one other and the receiver should print it.When I find time on parent process and try to print it on parent process It works fine.But when I try to send it through a pipe it writes a line with weird question marks and a z letter.I commented the last line in case if someone tries to execute the code. SOrry for the messy code but I cannot fix it in my current keyboard.
#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include<signal.h>
#include<stdint.h>
#include<string.h>
#include<time.h>
void formatted_time(char* sender_name, char* receiver_name, char output[]);
void formatted_time( char* sender_name , char* receiver_name, char output[])
{
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[80];
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf,80 , "%Y-%m-%d %H:%M:%S",
nowtm);
sprintf(output, "%s: Time at %s is %s.", receiver_name, sender_name, tmbuf);
}
int main(int argc, char** argv)
{
char* parent="Parent";
char* child1="Child1";
char* child2="Child2";
char result[80];
char buffer[80];
int firstchild,secondchild,read1,read2,read3;
firstchild=fork();
int mypipe[2];
int mypipe2[2];
int mypipe3[2];
if(pipe(mypipe) == -1) {
perror("Pipe failed");
exit(1);
}
if(firstchild == 0) //first child
{
close(mypipe[1]); //Closing the output of pipe
sleep(3);
read1=read(mypipe[0],buffer,sizeof(buffer));
printf("%s\n",buffer);
}else{
secondchild=fork(); //Creating second child
if(secondchild == 0) //2nd child
{
sleep(6);
}else{ //Parent
close(mypipe[0]); //Closing the input of pipe
formatted_time(parent,child1,result);
write(mypipe[1],result,strlen(result)+1);
//printf("%s\n",result);
Upvotes: 1
Views: 161
Reputation: 3659
You are forking the first child before you are creating the pipe. Thus, you create two distinct pipes: one in the parent and one in the child. Afterwards, if you read from the pipe created in the first child, the read
returns 0, indicating that no data has been read. Thus, data in the buffer is invalid and the printf
is prohibited. Always check the return code of API calls!
The user "nsilent22" already provided a good clean-up of your code. After adding 3 closing brackets }
at the end to close all blocks, you have at least move the fork after creating the pipe:
firstchild=fork();
if (firstchild == 0) { // first child
And at the read call, you should check the return code:
read1=read(mypipe[0],buffer,sizeof(buffer));
if (read1 <= 0) {
printf("read failed with code %d\n, ", read1);
} else {
printf("%s\n",buffer);
}
Upvotes: 1
Reputation: 2863
Your problem is you do a fork
call before you create your pipe. So in fact you read
reads nothing, and your printf
prints garbage that was on the stack where buffer
was allocated.
Here is your code fixed. I also added a wait
call in the parent to avoid child printing to the console out of nowhere :)
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/wait.h>
void formatted_time(char *sender_name,char *receiver_name, char output[]) {
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[80];
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf,80, "%Y-%m-%d %H:%M:%S", nowtm);
sprintf(output, "%s: Time at %s is %s.", receiver_name, sender_name, tmbuf);
}
int main(int argc, char** argv) {
char* parent="Parent";
char* child1="Child1";
char result[80];
char buffer[80];
int firstchild, secondchild, read1;
int mypipe[2];
if (pipe(mypipe) == -1) {
perror("Pipe failed");
exit(1);
}
firstchild=fork();
if (firstchild == 0) { // first child
close(mypipe[1]); //Closing the output of pipe
sleep(3);
read1 = read(mypipe[0], buffer, sizeof(buffer));
printf("%d %s\n", read1, buffer);
} else {
secondchild=fork(); //Creating second child
if(secondchild == 0) { //2nd child
sleep(6);
} else { //Parent
close(mypipe[0]); //Closing the input of pipe
formatted_time(parent, child1, result);
int w;
w = write(mypipe[1], result, strlen(result)+1);
printf("%d bytes written\n", w);
wait(NULL);
}
}
return 0;
}
Upvotes: 2