Создание нового процесса в Unix осуществляется системным вызовом fork()
который создаёт точную копию текущего процесса. Копируются все структуры данных в ядре и в пространстве пользователя, а значит и таблица открытых файлов. Таким образом дочерний процесс наследует все открытые файлы родительского процесса.
В таблице виртуальных Inode во время вызова fork()
счётчики числа открытий файлов увеличиваются на количество ссылающихся на них файловых дескрипторов нового процесса.
Вызов exec("exefile",...)
загружает в память существующего процесса код и данные из файла exefile. Все открытые файлы сохраняют своё состояние, кроме тех, которые помечены флагом "O_CLOEXEC". Помеченные файлы закрываются. Исполняемый файл exefile не занимает файловый дескриптор, но так же считается открытым, т.е. exec()
увеличивает счётчик числа открытий в таблице виртуальных Inode.
Благодаря цепочке вызовов fork()
- exec()
и наследованию открытых файлов shell при запуске внешней программы создаёт новый процесс с помощью fork()
, а в нём перед вызовом exec()
может переназначить файлы стандартного ввод-вывода, которые будут унаследованы запускаемой программой.