How can I close my child file descriptors when killing the parent process?
I've created a program that does the following:
Fork 2 child processes.
Process 1 is a reader. It reads from STDIN_FILENO and writes to STDOUT_FILENO with scanf/printf. But I use dup2 to redirect to a named pipe (let's call it npipe).
Process 2 is a writer. I redirect STDIN_FILENO to npipe so that I can use scanf from that pipe. I redirect STDOUT_FILENO to another file called "output_file" so that I can use printf to write.
Reading / Writing is done in a while(1) loop;
while(1){
scanf("%s",word);
printf("%s",word);
}
If I use CTRL+C (send SIGTERM signal to the parent), any data that was written in "output_file" is lost. Nothing is inside there. I think it's because I kill the processes while the files are opened?
I used a word that stops both child processes when read; in this case, I do have everything in my "output_file".
How can I close the files when using SIGTERM? / Can I somehow force my process to write into "output_file" so that no data is lost when suddenly closing?
I tried closing and opening the file after each writing. Still losing all the written data? Is this because of the redirect?
void read_from_pipe(void)
{
char command[100];
int new_fd = open(pipe_name,O_RDONLY,0644);
int output_file = open("new_file",O_CREAT|O_WRONLY|O_APPEND,0644);
dup2(new_fd,0);
dup2(output_file,1);
while(1)
{
scanf("%s",command);
if(strcmp(command,"stop")==0)
{
close(output_file);
close(new_fd);
exit(0);
}
else
printf("%s ",command);
close(output_file);
output_file = open("new_file",O_CREAT|O_WRONLY|O_APPEND,0644);
}
}
Managed to attach correct signal handlers, yet data is still not written even though I close my files! Why is that?
You problem is (likely) not to do with closing the file descriptors, it's with flushing the FILE pointers. Note that FILE pointers and file descriptors are two different things.
You call printf
, which does NOT write to STDOUT_FILENO (a file descriptor), it writes to stdout (a FILE pointer), which generally just buffers the data until it has a reason to write it to the underlying file descriptor (STDOUT_FILENO).
So you need to ensure your data that you write to stdout is actually written to STDOUT_FILENO. The easiest way to do that is to stick an fflush(stdout);
after the printf call to manually flush it, giving you fine-grained control over when stuff is written. Alternately, you can call setbuf(stdout, 0);
to make stdout unbuffered, so every write will be flushed immediately.