Причиной двухступенчатой является гибкость. Между этими двумя шагами вы можете изменить контекст дочернего процесса, который будет наследовать вновь исполняемая программа.
Некоторые вещи, которые вы можете изменить:
- Файловые дескрипторы
- ID пользователя / группы
- ID группы процессов и сеансов
- Текущий каталог
- Пределы ресурса
- Планирование приоритета и сходства
- Маска создания файла (umask)
Если вы не разделили fork и exec и вместо этого имели один системный вызов, похожий на spawn, то для каждого из этих атрибутов процесса потребовались бы аргументы, если вы хотите, чтобы они устанавливались по-разному в дочернем процессе. Например, см. Список аргументов для CreateProcess в Windows API.
С помощью fork / exec вы изменяете любые наследуемые атрибуты процесса, которые хотите использовать в дочернем процессе, прежде чем запускать новую программу.
Настройка файловых дескрипторов является одной из наиболее распространенных вещей, которые необходимо изменить в контексте дочернего процесса. Если вы хотите захватить выходные данные программы, вы обычно создаете канал в родительском элементе с помощью системного вызова pipe (2), а после fork (2) вы закрываете конец записи в родительском процессе и закрываете прочитайте end в дочернем процессе перед вызовом execve (2). (Вы также будете использовать dup (2), чтобы установить дочерний конец канала в дескриптор файла 1 (stdout)). Это было бы либо невозможно, либо ограничительно в одном системном вызове.