Как я могу удержать execv от уничтожения моей программы?

Мое задание - написать простую оболочку Linux. Я на внешних командах. Нам нужно использовать 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

сейчас я только проверяю это с помощью ls. ls запускается точно так, как должно, но программа закрывается сразу после успешного выполнения execv. Можно ли как-нибудь использовать execv для проверки правильности пути и продолжения работы программы после успешного выполнения execv?

2 ответа

Семейство функций exec не убивает ваш процесс. Они заменяют существующий образ процесса тем, который вы выполняете.

По сути, он работает так, как будто этот процесс (с его PID и связанными ресурсами ядра) остается прежним, за исключением того, что весь код из старого образа удаляется и заменяется кодом из программы, который затем загружается в память и инициализируется, как если бы это был новый процесс в целом. PID не изменяется, поэтому, если вы хотите создать дочерний процесс с собственным PID, вам нужно использовать другую функцию.

Правильный способ продолжить - это сначала разветвиться и использовать exec* из дочернего процесса. Таким образом, вы можете использовать функцию ожидания в родительском экземпляре, чтобы дождаться завершения дочернего процесса и возврата управления.

+--------------+             +--------------+                             +----------------------+
|Parent process|+---fork()-->|Parent process|+---------wait()------------>|Parent process resumes|
+--------------+      +      +--------------+                             +----------------------+
                      |                                                               +
                      |                                                               |
                      |                                                               |
                      |      +-------------+              +-----------------+         |
                      +----->|Child process|+--execv()--->|New process image|+--exit--+
                             +-------------+              +-----------------+

Различные формы exec() фактически заменяют текущий образ процесса запрашиваемым. Они не порождают новый процесс. Так что вам нужно сделать это самостоятельно, используя fork().

Другие вопросы по тегам