views:

101

answers:

2

Hi, so basically I want "cmd_limit" to take a number in seconds which is the maximum time we'll wait for the child process (safe to assume there's only one) to finish. If the child process does finish during the sleep, I want cmd_limit to return pass and not run the rest of the cmd_limit code. Could anyone help me do this, here's what I've got so far..

int cmd_limit( int limit, int pid ) {

    signal( SIGCHLD, child_died );
    sleep( limit );
    kill( pid, SIGKILL );
    printf("killin'\n");
    return PASS;
}

void child_died( int sig ) {

    int stat_loc; /* child return information */
    int status; /* child return status */

    waitpid( -1, &stat_loc, WNOHANG );

    if( WIFEXITED(stat_loc) ) { // program exited normally
        status = WEXITSTATUS( stat_loc ); /* get child exit status */
    }

    printf("child died: %s\n", signal);

}
+1  A: 

Do you just mean something like this?

bool childDied;

int cmd_limit( int limit, int pid ) {
    childDied = FALSE; 
    signal( SIGCHLD, child_died ); 
    sleep( limit ); 
    if (!childDied)
    {
      kill( pid, SIGKILL ); 
      printf("killin'\n"); 
    }
    return PASS; 
} 

void child_died( int sig ) {
    int stat_loc; /* child return information */ 
    int status; /* child return status */ 

    childDied = TRUE; 

    waitpid( -1, &stat_loc, WNOHANG ); 

    if( WIFEXITED(stat_loc) ) { // program exited normally 
        status = WEXITSTATUS( stat_loc ); /* get child exit status */ 
    } 

    printf("child died: %s\n", signal); 

} 
torak
this is right, except for the fact that if limit = 200 and the child dies in 10 seconds, we'd still have to wait 200 seconds to do anything else in the program..
Gary
@Gary: If that is a concern you can replace the one large call to sleep with several shorter ones using a loop counter that counts to the desired total. Each time through the loop check if the child process has exited.
torak
+2  A: 

kill returns 0 if a signal was sent, and -1 if no signal was sent. No signal can be sent if the process has already exited, so the return value from kill can be used to tell you if the process was killed by kill or already dead.

In addition, you could use one of the wait system calls to look into the state change (including exit ) of the child process.

You should also look into signal handling in the parent process for SIGCHLD, which the parent would receive when the child changes state (including exit ) and will also kick the parent out of a sleep state (though on some systems the sleep function may restart sleeping).

Using wait and/or SIGCHLD you could make the parent finish sooner if the child exited within your time limit.

You should note that you probably should call wait for child processes to exit so that you don't create zombies (processes which have called exit but have to be kept around in case the parent wants to look at their exit status).

Another thing you'll want to look into is the errno value EINTR which system calls can set if they were interrupted by a signal.

From your command line type:

man errno
man 2 wait
man 2 sigaction

for more information about the things I've talked about.

nategoose
good information, i'll look into that - thanks :)
Gary