1

I'm trying a small unit-testing here. But the program doesn't work as I expected.

    char *args[2];
    args[0] = (char*)"/usr/bin/firefox";
    args[1] = NULL;
    pid = fork();
    printf("forked and my pid is %d\n",pid);
    //check for errors
    if (pid<0){         
        printf("Error: invoking fork to start ss has failed, Exiting\n ");
        exit(1);
    }
    //the child process runs firefox
    if (pid==0){        
        if (execv(args[0],args)<0){
            perror("Error: running s with execvp has failed, Exiting\n");
        }
        printf("IVE BEEN KILLED\n");            
    }
    //dad is here
    printf("DAD IS GOING TO KILL U\n");
    if (pid>0){
        sleep(3);
        kill(get_pidof(string("firefox")),SIGUSR1);
    }

Now, I would expect the program to run as follow: 1.the child runs firefox (which it does) 2.the dad prints DAD IS GOING TO KILL U (so far so good) 3.the firefox would open for 3 seconds and then close (does that too) 4.the child process would finish running execv and print "IVE BEEN KILLED". This doesn't happen.

My aim is to know that the program which execv ran has finished by raising a few flags right after execv continues running (where the ive been killed printf is). I have a code of a few thousand lines and don't want to use other methods, unless necessary.

Thanks

Rook
  • 5,734
  • 3
  • 34
  • 43
Alon_T
  • 1,430
  • 4
  • 26
  • 47

2 Answers2

2

execv() replaces the current process with a new process. When firefox is started via execv() the printf("IVE BEEN KILLED\n") essentially no longer exists in the process and will never be executed (see man execv). It would be possible for the parent process to wait for the child, firefox, to exit by using wait() or to be alerted to the death of the child process via a signal (e.g. signal(SIGCHLD, child_exit_handler)).

hmjd
  • 120,187
  • 20
  • 207
  • 252
  • ok. when I manually close the firefox from its UI it does print IVE BEEN KILLED. Is there a way to make that happen from the code? – Alon_T Nov 08 '12 at 14:21
  • ok. when I manually close the firefox from its UI it does print IVE BEEN KILLED. – Alon_T Nov 08 '12 at 14:21
  • @user1432779, presumably you mean _doesn't_ print `I'VE BEEN KILLED`. There would be way to do that from the child process as it is firefox so any lines after the call to `execv()` should never be called unless it failed. The only would be for the parent process to print that line. – hmjd Nov 08 '12 at 14:24
0

You've killed the child and it doesn't catch the signal so it just dies. At least it would if exec returned, but it doesn't. So you'd only execute the print if the exec failed.

If you want to know if your child has finished, use the wait call.

Note also that as your child doesn't exit, it'll then execute the parent pid's code, which could be interesting.

Tom Tanner
  • 9,244
  • 3
  • 33
  • 61
  • But The father can't be idle until the child dies. It needs to keep running, and in turn will eventually check if flags were raised that show that the execv finished(or that the process execv started has finished) – Alon_T Nov 08 '12 at 14:17
  • Oh..so the kill didn't kill the original child process, but killed the firefox process which replaced it? – Alon_T Nov 08 '12 at 14:19
  • @user1432779, firefox is the child process. – hmjd Nov 08 '12 at 14:20
  • @nos, I alluded to that in my answer. – hmjd Nov 08 '12 at 14:32