2

Say I create a pipe between child and parent process and the child process ends normally, will child process's pipes been closed automatically?

Also, If the child process also has a child process and the child process ends with a segmentation fault, will it also kill my grandchild process? I mean remove it from the process table(I don't need to wait for it).

EDIT: For example for the following code I generate a segmentation fault in the child process and try to wait for it in the parent process. After I run the program, waitpid return -1, but when I check WIFEXITED(status) it seems like the child process program exit normally. And I got a

Killing child process failed: No such process

error try to kill my grandchild process. I wonder if this is because segmentation fault automatically close both child and grandchild process?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>


int main( void ) {

    pid_t childpid;
    int ends[ 2 ];
    pipe( ends );
    if ( ( childpid = fork() ) == -1 ) {
        perror( "fork failed" );
        exit( 0 );
    }
    if( childpid == 0 ) {
        pid_t cpid;
        if ( ( cpid = fork() ) == -1 ) {
            perror( "fork failed" );
            exit( 0 );
        }
        if ( cpid == 0 ){
            while(1);
        }   
        else{
            printf("cpid is : %d\n",cpid);
            char msg[32];
            sprintf( msg, "%d", cpid );
            printf("cpid con is : %s\n", msg);
            if( write( ends[ 1 ], msg, 32 ) == -1 ) {
                perror( "Write failed" );
                exit( 0 );
            }
            char *s = NULL;
            *s = 15;
            while(1);
        }
    }
    else{
        printf("childpid is : %d\n",childpid);
        char msg[ 32 ];
        int cpid;
        if( read( ends[0], msg,32 ) == -1 ) {
            perror("read failed");
            exit( 0 ); 
        }
        cpid = atoi( msg );
        int status;
        while(1) {
            if ( waitpid( childpid, &status, WNOHANG ) == -1 ) {
                //printf( "%d\n", WIFEXITED(status) );
                if ( kill( cpid, 9 ) == -1 ) {
                    perror( "Killing child process failed" );
                    exit( 0 );
                }
                /*if ( kill( cpid, 9 ) == -1 ) {
                    perror( "Killing child process failed" );
                    exit( 0 );
                }*/

            }
        }
    }
    return 0;
}
user5574376
  • 371
  • 1
  • 5
  • 12
  • 2
    Yes to the first. No to the second. – kaylum Mar 08 '16 at 23:14
  • Take a good look at the last while loop. You wait on your child. That wait will likely succeed on the first try. Your child's status is reaped and the pid no longer belongs to you. Next iteration. You wait on a pid that doesn't belong to you -- that wait is bound to fail. You attempt to kill the grandchild -- you succeed. Next iteration. Your wait continues failing and now the kill fails too. You exit. – Petr Skocik Mar 09 '16 at 15:46
  • 1
    Yes, I just figure out a couple seconds ago, such a stupid mistake. Thanks anyway! – user5574376 Mar 09 '16 at 15:48
  • What you should do is `while(waitpid(...)==-1) {;}`. Also you can replace those other `while(1) ;` with `pause();`. Avoid SIGKILL (9), reads and writes can succeed partially and `pipe` can fail. – Petr Skocik Mar 09 '16 at 15:49
  • if the pipe is a 'named pipe' then the pipe will still exist, but be closed when the process crashes. If the pipe is 'not' a 'named pipe' then the pipe disappears when the process crashes. – user3629249 Mar 09 '16 at 19:59

1 Answers1

7

The OS will close all the filedescriptors associated with the process that has died or exited. If that closes the last filedescriptor pointing to a pipe's read end, then writes to the write end will start generating SIGPIPEs (fds are ref-counted references to vnode entity behind them).

If a parent dies, its child will be reparented to init. init will wait on it. (Grandparents can't wait on grandchildren anyhow).

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • 1
    So will init will never kill the grandchild process? Just wait until it terminates? – user5574376 Mar 09 '16 at 02:59
  • 1
    @user5574376 That is correct. The process will still belong to a process group and may get killed because that process group was e.g., sent SIGINT via job control (^C), or SIGHUP when the process goes to sleep and its process group becomes on orphan process group. – Petr Skocik Mar 09 '16 at 09:57
  • I understand when a child process ends normally, my grandchild process will be adopted by init, but what happen when child process generate a seg fault. When I try to kill a grandchild process through its pid after my child process generating a segmentation fault. I got a no such process error. But when I did not generate a seg fault and just simply kill the child process, I can successfully kill the grandchild process without no such process error. – user5574376 Mar 09 '16 at 14:07
  • It doesn't matter how the process ends. If it child survives it, the child will get reparented. If you've got a concrete question with a concrete piece of code, ask it. – Petr Skocik Mar 09 '16 at 14:25