Thread: Child process status

  1. #1
    Registered User
    Join Date
    Jul 2008
    Posts
    12

    Child process status

    I am attempting to use "kill(pid, 0) == 0" to determine if a child process is running. It doesnt seem to be working as advertised. I have a parent C program that spawns a child C program on a unix box. Supposedly, the 'kill' statement listed above will return true if the 'pid' is still running, but wont return 0 if it isnt. In my case, I run the 'kill' command after I have manually killed the child process and it still says the child process (a.out) is running. Here is a snippet of the code that I ran:

    parent.c

    Code:
    int main()
    {
       char *args[2];
       int p1;
    
       p1 = vfork();
       if (p1 == 0)
       {
          args[0] = "./a.out";
          args[1] = NULL;
          execv("./a.out", args);
       }
    
       sleep(20);
    
       if (kill(p1, 0) == 0)
       {
          printf ( "running");
        }
        else
       {
          printf ("not running");
       }
    child process
    Code:
    int main()
    {
       char *xxx;
       sleep(2);
       strcpy(xxx, "somethign");   /* to manually kill this program */
    }

    any ideas?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    If you want to make your code crash, I'd say that you should change this:
    Code:
    int main()
    {
       char *xxx = NULL;
       sleep(2);
       strcpy(xxx, "somethign");   /* to manually kill this program */
    }
    As your code stands, it MAY succeed to memcopy a 10 byte string into whatever happens to be the value of xxx - you can't know it's value so it may crash one day, and not another day [particularly, it will be sensitive to changes in compiler settings for example].

    As to killing your application, perhaps you want to use something other than zero as the signal number, as zero is not defined as a signal, and it is unclear to me what it does. For example SIGINT (CTRL-C) or SIGKILL (kill -9) would make more sense?

    Also, if you don't get zero back (particularly, if you get -1) then you should look into what errno contains, for example use perror("kill") may give you an error message to indicate why it didn't kill the process.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    One way to know if a child is running or not is to register the SIGCHLD signal in the parent process. In your signal handler for the SIGCHLD signal, set a global variable to "true". Then, you only need to check whatever this variable is set to true or not to see if the child terminated or not.

    Code:
    #include ...
    
    int childTerminated = 0;
    
    void sigHandler(int sigNum)
    {
        if (sigNum == SIGCHLD)
        {
            childTerminated = 1;
        }
    }
    
    int main()
    {
        pid_t child_pid;
        struct sigaction sa = ...;
        sigaction(SIGCHLD, &sa, NULL);
    
        ...
    
        child_pid = fork();
        if (child_pid)
        {
            ...
        }
    
        sleep(...)
        if (childTerminated)
        {
             // Child process terminated
        }
    
        return 0;
    }
    I guess that would work. At least, that's how I would do it. I guess there's other way to do it.
    I hate real numbers.

  4. #4
    Registered User
    Join Date
    Jul 2008
    Posts
    12

    Thanks

    Thanks, guys, for the responses.

    We have tried the signal handling method also, but sometimes the signal doesnt register or return to the parent process. Not sure why. So, this other method I posted about was insurance.

    I originally just killed the child processing manually from the command line. The 'strcpy' idea was to see if there is any difference if the application dies internal as opposed to being directly killed. Neither one seems to make a difference. The parent process uses the 'kill(pid, 0)==0' and it always comes back non zero, whether the child process is running or not. I thought maybe there was something else that I was missing????

    thanks again.
    Bill

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by paraglidersd View Post
    Thanks, guys, for the responses.

    We have tried the signal handling method also, but sometimes the signal doesnt register or return to the parent process. Not sure why. So, this other method I posted about was insurance.

    I originally just killed the child processing manually from the command line. The 'strcpy' idea was to see if there is any difference if the application dies internal as opposed to being directly killed. Neither one seems to make a difference. The parent process uses the 'kill(pid, 0)==0' and it always comes back non zero, whether the child process is running or not. I thought maybe there was something else that I was missing????

    thanks again.
    Bill
    Most likely, kill returns not-zero (specifically -1) because it doesn't like signal 0 - my guess is that if you do perror() in the "not zero" branch of your if, it will say "Invalid" something or other - the errno will be EINVAL. I would try it out if I had a Linux machine currently running, but it's hidden deep in a cupboard at the moment.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Quote Originally Posted by paraglidersd View Post
    The parent process uses the 'kill(pid, 0)==0' and it always comes back non zero, whether the child process is running or not.
    Well, if you look at the documentation (I'm using the man pages coming with my distribution, but I guess this is the same thing on every Linux distribution), you will see that, under the section "Return value" for "man 2 kill":

    On success (at least one signal was sent), zero is returned. On error, -1 is returned, and errno is set appropriately.
    Since you aren't sending any signal, well, don't be surprised if the function return a non-zero value.

    I wrote this little program, and indeed, I get the behavior I was expecting

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #undef NDEBUG       // For cheap error checking
    #include <assert.h>
    #include <signal.h>
    #include <unistd.h>
    
    int is_terminated = 0;
    
    void my_sig_handler(int signum)
    {
        if (signum == SIGCHLD)
        {
            is_terminated = 1;
        }
    }
    
    int main()
    {
        struct sigaction sa;
        pid_t child_pid;
    
        sa.sa_handler = my_sig_handler;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;
        assert(sigaction(SIGCHLD, &sa, NULL) != -1);
    
        assert((child_pid = fork()) != -1);
        if (child_pid == 0)
        {
            sleep(1);
            exit(0);
        }
    
        sleep(2);
        if (is_terminated)
        {
            printf("Child process has terminated\n");
            // Here you could catch the exit code of the child with a call to wait()
        }
    
        else
        {
            printf("Child process has not terminated\n");
        }
    
        return 0;
    }
    I hate real numbers.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Jul 2008
    Posts
    12

    Thanks

    Awesome. Thanks for your help on this matter. Much appreciated.

    Bill

  9. #9
    Registered User
    Join Date
    Jul 2008
    Posts
    12

    question

    question: is there any other way, other than signal handlers, to determine if a child process is running?

    I misspoke when I stated that the kill command returned non-zero. it always returned zero whether the child process was running or not. also, looking at errno after the second 'kill' command it had the value 4 (interrupted process). Odd.

    So, I cannot seem to get the kill command to give me status. And I would like another way (other than signal handlers) to go out and 'poll' the system to see if a process is still active. Any ideas?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. init adopts zombie process?
    By password636 in forum Linux Programming
    Replies: 4
    Last Post: 07-01-2009, 10:05 AM
  2. create a child process that creates a child process
    By cus in forum Linux Programming
    Replies: 9
    Last Post: 01-13-2009, 02:14 PM
  3. Replies: 3
    Last Post: 10-15-2008, 09:24 AM
  4. get the status of the child process
    By mystic-d in forum C Programming
    Replies: 9
    Last Post: 11-17-2007, 04:59 AM
  5. process programming
    By St0rM-MaN in forum Linux Programming
    Replies: 2
    Last Post: 09-15-2007, 07:53 AM