1

My assignment is to write a simple linux shell. I'm on external commands. We need to use execv.

for (int i = 0; i < count; i++){
  char path[1024];
  strcpy(path, PATHS[i]);         // PATHS is an array of cstrings, the paths in $PATH
  strcat(path, "/");
  strcat(path, command[0]);       // command and commands are essentially the same
  printf("%d %s",i,path);         // they are essentially argv[]
  if (!execv(path, commands))     // for ls -l $HOME
    break;                        // commands[0] = ls [1] = -l [2] = my home dir

right now I'm only testing it with ls. ls runs exactly as it should, but the program closes immediately after execv succeeds. Is there any way for me to keep using execv to check for the correct path and for the program to continue running after execv succeeds?

d0m1n1c
  • 157
  • 4
  • 16

2 Answers2

6

The exec family of functions do not kill your process. They replace the existing process image with the one you execute.

Basically, it works as if, that process (with its PID and associated kernel resources) remains the same, except all the code from the old image is removed and replaced by the code from the program that is then loaded into memory and initialized as if it were a new process altogether. The PID does not change, so if you want to create a child process with its own PID, you have to use another function.

The correct way to proceed is to fork first, and use exec* from the child process. This way you can use the wait function in the parent instance to wait for the child to terminate and take control back.

+--------------+             +--------------+                             +----------------------+
|Parent process|+---fork()-->|Parent process|+---------wait()------------>|Parent process resumes|
+--------------+      +      +--------------+                             +----------------------+
                      |                                                               +
                      |                                                               |
                      |                                                               |
                      |      +-------------+              +-----------------+         |
                      +----->|Child process|+--execv()--->|New process image|+--exit--+
                             +-------------+              +-----------------+
SirDarius
  • 41,440
  • 8
  • 86
  • 100
  • when `execv` replace the existing process, what will happen to the old process? – sujin Jan 30 '14 at 09:20
  • the executed **image** changes. The process still exists, and the PID remains the same. Editing my post to make that clearer. – SirDarius Jan 30 '14 at 09:25
  • Thanks it is clear now. if you can please explain more about this line `if you want to create a child process with its own PID, you have to use another function.` – sujin Jan 30 '14 at 09:34
  • @sujin, the explanation is right under the sentence, fork/exec/wait. You can find a huge number of examples with Google, like http://www.cs.duke.edu/courses/spring01/cps110/slides/proc-ux/sld012.htm – SirDarius Jan 30 '14 at 09:53
2

The various forms of exec() actually replace the current process image with the requested one. They do not spawn a new process. So you need to do it yourself, using fork().

John Zwinck
  • 239,568
  • 38
  • 324
  • 436