Thread: Signals, fork(), wait() and exec()

  1. #1
    Registered User
    Join Date
    Jul 2007
    Posts
    9

    Signals, fork(), wait() and exec()

    Hi there,

    so I think that wait() waits until a child terminates (either through signal or exit). So let's say the father makes a fork() and then just wait(). The child uses exec() to execute another program. Well, and now what's happening? The exec call never comes back (in case it was succesfull). So how long does the father waits now?

    Here's the code I'm using:
    Code:
    #include <stdio.h>
    #include <fcntl.h>  
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int main() {
       pid_t pid ;
       if ( ( pid = fork () ) < 0 ) {
          perror ("fork");
          return 1;
       }
       if ( pid == 0 ) {
          close (1);
          if ( open("XXX", O_WRONLY | O_CREAT | O_TRUNC, 0666) < 0) {
             perror("open");
             return 2;
          }
          execlp("cat", "cat" ,NULL);
          perror("exec");
          return 3;
       } else {
          wait (0); //for how long does the father waits?
          return 0;
       }
    }
    In this particular case I think that the father remains until cat is forced to exit, but I'm not sure.

    Any suggestions are welcome

    Thanks
    TurboToJo

  2. #2
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    I think the father waits indefinitely....
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    wait() will wait until the process terminates [unless you abort the process itself] - whether that happens in milliseconds or years later doesn't make any difference. wait() doesn't stop waiting.

    You should really specify an integer pointer (address of an integer) to store the status for wait() in.

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

  4. #4
    Registered User
    Join Date
    Jul 2007
    Posts
    9
    Ok, so the father waits with wait() until its son is done with the exec thing? Isn't that weird as exec doesnt return anything. So how come that the father knows when its son is terminated (that is the exec process is done).

    Thank you guys
    TurboToJo

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The way that wait() works it that there is a mechanism in the kernel that knows when this process finishes, and that's when the status variable in wait() gets set, and the wait() finishes.

    exec() can not return [assuming it's a success] since it loads a different piece of code, which overwrites where exec() would come back to. So there is "nowhere to go back to" from exec().

    In other OS's the mechanism of creating a new process is slightly different, the fork() and exec() are often combined into a "CreateProcess()" or similar function, that creates another process and loads the executable. In this case, the return value from CreateProcess() is one of three things:
    1. Failure to create a new process (matches fork()).
    2. Failure to load the executable (matches exec()).
    3. The result of the execution itself (matches wait()).

    Often you can also issue a flag to CreateProcess() to say "Don't wait for the process to finish".

    There are some good reasons to have the "create a new process" split into multiple separate function. There are other reasons to make it one function. Which is preferred depends on the implementor of the OS.

    --
    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
    Registered User
    Join Date
    Jul 2007
    Posts
    9

    Solution

    Ok, so I checked the exit status and that's what I found (please correct me if I'm wrong):

    the father waits with this function wait() until one child terminates. If this child is doing an exec, the father waits until this exec procedure is done.

    I edited my code a bit, to test it:
    Code:
    #include <stdio.h>
    #include <fcntl.h>  
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int main() {
       pid_t pid ;
       if ( ( pid = fork () ) < 0 ) {
          perror ("fork");
          return 1;
       }
       if ( pid == 0 ) {
          close (1);
          if ( open("XXX", O_WRONLY | O_CREAT | O_TRUNC, 0666) < 0) {
             perror("open");
             return 2;
          }
          sleep(2);  //EDITED: to see if the father waits
          execl("/bin/ls", "ls" , ".", NULL);  //EDITED as ls exit automatically
          perror("exec");
          return 3;
       } else {
          int status;
          wait (&status);  //EDITED to see what's going on
          if (WIFEXITED(status))
             printf("CHILD exited with &#37;d\n", WEXITSTATUS(status));
    
          if (WIFSIGNALED(status))
             printf("signaled by %d\n", WTERMSIG(status));
    
          if (WIFSTOPPED(status))      
             printf("stopped by %d\n", WSTOPSIG(status));
    
          printf("DONE FATHER\n");
          return 0;
       }
    }
    So, I played around a bit and when giving a wrong command to exec leads to a return value of 3, which is correct. But the thing is that the father always waited till it got anything from his child.

    TurboToJo
    Last edited by DJTurboToJo; 03-18-2008 at 06:34 AM.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by DJTurboToJo View Post
    Ok, so I checked the exit status and that's what I found (please correct me if I'm wrong):

    the father waits with this function wait() until one child terminates. If this child is doing an exec, the father waits until this exec procedure is done.

    I edited my code a bit, to test it:
    <snip code>


    So, I played around a bit and when giving a wrong command to exec leads to a return value of 3, which is correct. But the thing is that the father always waited till it got anything from his child.

    TurboToJo
    Yes, that's how it's supposed to be. If you wanted it to do something else, please explain what.

    Note that fork() makes one process into two processes, so from that point, there are TWO SEPARATE processes. It just so happens that both have the same files open, and executing within the same code.

    You can do other things before you wait, if you want, the result will stay there until you call wait later on.

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

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The child remains the same child even after the call to exec(). It's just running a different binary image, is all. Forget about the exec(), it changes nothing.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why wait cursor still turning on?
    By Opariti in forum Windows Programming
    Replies: 0
    Last Post: 05-22-2009, 02:28 AM
  2. Procesees, fork(), wait() and exec()
    By Stewdent in forum Linux Programming
    Replies: 1
    Last Post: 02-20-2003, 11:34 AM