#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
int main(){
char buf[10];
pid_t pid = fork();
if (pid < 0){
printf("error fork\n");
exit(1);
}
if (pid == 0){
fgets(buf,5,stdin);
printf("Child : %s\n",buf);
}
else{
wait(NULL);
char* r = fgets(buf,5,stdin);
if (r == NULL){
printf("Parent : eof = %i\n",feof(stdin));
}
else {
printf("Parent : %s\n",buf);
}
}
return 0;
}
My program is very simple : a process is forked; the child process reads 4 characters from stdin and when it finishes, the parent process reads 4 characters from stdin.
Normally, if I write characters in stdin (before the fork) the child process should read the first 4 characters and then the parent process should read the next 4 characters. It seems quit logical as fork() duplicates the parent process, including the file descriptors and opened files.
But, when I execute
echo 'aaaaaaaaa' | ./my_program
I get
Child : aaaa Parent : eof = 1
It seems that stdin has been emptied by the child process when it finished. I having hard time explaining this behavior.
Can you help me ? :)
CodePudding user response:
Standard input is usually (Is stdout line buffered, unbuffered or indeterminate by default?) line buffered by default. Check this answer to see what exactly this entails.
If you want your program to work as expected, explicitly set your standard input to be unbuffered (before the fork()
call). This can be done like so:
setbuf(stdin, NULL);
Also see Should I set stdout and stdin to be unbuffered in C? for more implications of setting stdin
to be unbuffered.
CodePudding user response:
Try comment out after "else{"
//wait(NULL);