I have the folowing C code. The child is used to run test3, whose code will be below. The parent is used to pass the data to the child which will be redirected to STDIN of test3.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char *argv[]) {
int fd[2];
char buf[] = "HELLO WORLD!";
if(pipe(fd)){
perror("pipe");
return -1;
}
switch(fork()){
case -1:
perror("fork");
return -1;
case 0:
// child
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
close(fd[0]);
system("./test3");
default:
// parent
close(fd[0]);
FILE* stream = fdopen(fd[1],"w");
if(stream == NULL){ // error checking
printf("Error creating a file\n");
printf("%s\n", strerror(errno));
return -1;
}
// write data to pipe
fwrite(buf, 1,6,stream);
close(fd[1]);
fclose(stream);
}
printf("END~\n");
return 0;
}
And here is test3 code:
#include <stdio.h>
int main(){
char n[1000];
scanf("%s",n);
printf("%s\n",n);
}
My problem is the fdopen
in the parent's code returns NULL with the Bad file descriptor error
and I cannot figure out the reasons. Can anyone helps?
Thanks in advance.
The error is actually coming from the child, not the parent. After the child runs test3
with the system call, it falls through into the default:
case, trying to fdopen
the file descriptor it has already closed. Add break;
after the system call and the error will go away.
A second problem is the close(fd[1])
in the parent, which closes the file descriptor out from under the FILE pointer before it flushes the data you wrote with fwrite
. Either put an fflush(stream);
call before the close
or just get rid of the close
, as the fclose
will close the file descriptor.