Как я могу удержать 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().