Возвращается ли управление после "execvp ()"? - PullRequest
6 голосов
/ 19 мая 2010

if(pid == 0)
{
      execvp(cmd, args);
      // printf("hello"); // apparently, putting this or not does not work.
      _exit(-1);
}
else
{
      // parent process work
}

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

Но тогда зачем нужна _exit () ..? Случается ли так, что элемент управления возвращается к операторам post execvp ()?

Буду благодарен за любые указатели.

Спасибо

Ответы [ 4 ]

6 голосов
/ 19 мая 2010

Функция вернется в случае сбоя.

Если одна из функций exec возвращается к образу вызывающего процесса, произошла ошибка; возвращаемое значение должно быть -1, а errno должно быть установлено для указания ошибки.

_exit() позволяет правильно завершить процесс и вернуть код выхода, даже если exec не удается.

2 голосов
/ 19 мая 2010

Системный вызов execve() может завершиться ошибкой. Классическая причина для этого может быть, если файл не существует или не является исполняемым. execvp() обтекает execve(), добавляя поиск пути и обработку среды по умолчанию (практически всегда то, что вам нужно!), И поэтому добавляет еще несколько режимов отказа, в частности, пытается запустить что-то с простым именем, которое не находится на пути пользователя. В любом случае, сбой - это сбой, и вы не можете ничего сделать, когда это произойдет, кроме сообщения о том, что произошла ошибка, и получения (теперь бесполезного) дочернего процесса Out Of Dodge. (Самый простой способ сообщения об ошибках - напечатать сообщение об ошибке, возможно, с perror(), но есть и другие.)

Причина, по которой вам нужен _exit() в отличие от более нормального exit(), заключается в том, что вы хотите выйти из дочернего процесса , но вы не хотите запускать какой-либо зарегистрированный код очистки, связанный с родительским процессом. процесс. Хорошо, многое из этого может быть безвредным, но делать такие вещи, как запись прощальных сообщений в сокет или что-то в этом роде, было бы плохо, и зачастую совсем не очевидно, что было зарегистрировано в atexit(). Пусть родительский процесс беспокоится о своих ресурсах; ребенок в основном не имеет ничего, кроме своего стекового фрейма!

1 голос
/ 19 мая 2010

Если execvp не удалось, будет вызван _exit.

Страница пользователя

execvp гласит:

Возвращаемое значение
Если какая-либо из функций exec () вернется, произойдет ошибка. Возвращаемое значение -1, и глобальная переменная errno будет установлена ​​для указания ошибки.

0 голосов
/ 19 мая 2010

Стоит отметить, что вы обычно не хотите, чтобы статус выхода процесса был подписан (если важна переносимость). В то время как exec() может свободно возвращать -1 при сбое, он возвращает его, чтобы вы могли обработать этот сбой в дочернем коде.

Фактический _exit() статус ребенка должен быть 0 - 255, в зависимости от того, что errno было поднято.

...