0
votes

How can I close my child file descriptors when killing the parent process?

I've created a program that does the following:

  1. Fork 2 child processes.

  2. 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).

  3. 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?

1
You need to install a signal handler that will ensure your file is closed upon exit.sturcotte06
Tried to do it but it seems that the children are oblivious to it. Plus i do not know how to make a different handler for both of the children for the same signal.Eduard6421
If you fork your process after installing the signal handlers, your child processes will have the signal handler. You can then install another handler in your parent that will propagate the signal to children. Also, you can open your file with FSYNC flag.sturcotte06
Yeah,makes sense! That would be a natural solution; Okay but i tried the next thing and something was wrong again... I close the file after each writing yet data still isn't written in the file ..Eduard6421
"father"? why not use the standard "parent"?Attie

1 Answers

1
votes

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.