The child process is skiped, idk why... I used debugger and it doesn't give any clues why...only runs trhough the code ending with the printf of the parent process... Thanks in advance. Don't know what to say more my first time asking a question, it's asking me for details ... But I don't know what else to say, the purpose of the code is to run the "verificador" program which is a program that verifies in a given string how many forbidden words exist, so I've tried this, where my "server" would communicate through a pipe with "verificador" and than save the number of forbidden words to give to the "client".
#include <sys/errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
void myabort(const char * msg, int exit_status){
perror(msg);
exit(exit_status);
}
int main(int argc,char *argv[])
{
pid_t pid;
int fd[2],newfd,nbytes;
int status;
char word[]="filipe";
FILE* f;
if(pipe(fd)<0) myabort("unable to create unamed pipe",-1);
switch(pid=fork()){
case -1: // Error
myabort("Unable to fork()",-3);
break;
case 0:
printf("CHILD PROCESS");
if(close(fd[0])==-1) myabort ("CHILD: Error while closing the read end of the pipe.",-4);
if(close(STDOUT_FILENO)==-1) myabort ("CHILD: Error while closing the standard output.",-4);
if(dup(fd[1])==-1) myabort("CHILD: Error while duplicating the pipe write end",-5);
if(close(fd[1])==-1) myabort ("CHILD: Error while closing the original write end descriptor of the pipe.",-4);
//fprintf(stdout, "%s", word);
write(1,word,sizeof(word));
break;
default:
printf("PARENT PROCESS");
wait(&status);
close(STDIN_FILENO);
newfd = dup(fd[0]);
close(fd[0]);
close(fd[1]);
f = fdopen(newfd, "r");
if(f == NULL) myabort("Error opening new file descriptor.", -1);
execl("verificador", "verificador", "palavras_proibidas", NULL);
break;
}
}
The problem is as follows:
Here, you write a string to the stdout stream:
printf("CHILD PROCESS");
This output is buffered, due to line buffering when stdout is a terminal. Usually, this buffer is implicitly flushed when the program ends, showing the output. But here:
if(close(STDOUT_FILENO)==-1) myabort ("CHILD: Error while closing the standard output.",-4);
if(dup(fd[1])==-1) myabort("CHILD: Error while duplicating the pipe write end",-5);
you close the stdout filedescriptor (1), which was connected to your terminal, and connect it to your pipe. So, when the stdout-stream is (implicitly or explicitly) flushed after this, the output goes to the pipe!
You have to make sure, that the output is flushed before closing the filedescriptor, to not only make sure, that it is printed to the terminal, but also to not corrupt the communication through the pipe with your verificator-process. Because, as it stands, your verificator process will receive the string
"filipe\0CHILD PROCESS"
when the stdout stream is implicitly flushed when your child process ends (i.e. returns from main()
)
The easiest and safest way to fix this situation is to call
fflush(stdout);
directly before you close filedescriptor 1.