Официальный документ о ВСЕХ шагах очистки после форка перед exec

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

Но что еще мне нужно сделать?

Есть ли где-нибудь исчерпывающий документ, в котором перечислены все вещи, которые вы, возможно, захотите почистить при разветвлении дочернего процесса, чтобы обеспечить ему хорошую стандартную среду выполнения?

В настоящее время я работаю в Linux, но мне бы хотелось, чтобы документ содержал подробности и для других Unix-систем, возможно, со способами их автоматической проверки.

1 ответ

fork(3) предоставляет полный список. Это немного длинно, чтобы цитировать здесь, но согласно политике SO я сделаю это так или иначе:

Функция fork() должна создать новый процесс. Новый процесс (дочерний процесс) должен быть точной копией вызывающего процесса (родительский процесс), за исключением случаев, подробно описанных ниже:

  • Дочерний процесс должен иметь уникальный идентификатор процесса.
  • Идентификатор дочернего процесса также не должен совпадать ни с одним идентификатором группы активных процессов.
  • Дочерний процесс должен иметь другой идентификатор родительского процесса, который должен быть идентификатором процесса вызывающего процесса.
  • Дочерний процесс должен иметь свою собственную копию файловых дескрипторов родителя. Каждый из файловых дескрипторов дочернего элемента должен ссылаться на одно и то же описание открытого файла с соответствующим файловым дескриптором родительского файла.
  • Дочерний процесс должен иметь свою собственную копию потоков открытых каталогов родителя. Каждый открытый поток каталогов в дочернем процессе может совместно использовать позиционирование потока каталогов с соответствующим потоком каталогов родительского процесса.
  • Дочерний процесс должен иметь свою собственную копию дескрипторов каталога сообщений родителя.
  • Значения дочернего процесса tms_utime, tms_stime, tms_cutime и tms_cstime должны быть установлены в 0.
  • Время, оставшееся до тех пор, пока сигнал будильника не будет сброшен на ноль, и будильник, если таковой имеется, должен быть отменен; см. тревогу ().
  • Все значения semadj должны быть очищены.
  • Блокировки файлов, установленные родительским процессом, не должны наследоваться дочерним процессом.
  • Набор сигналов, ожидающих для дочернего процесса, должен быть инициализирован пустым набором.
  • Интервальные таймеры должны быть сброшены в дочернем процессе.
  • Любые семафоры, открытые в родительском процессе, также должны быть открыты в дочернем процессе.
  • Дочерний процесс не должен наследовать какие-либо блокировки памяти адресного пространства, установленные родительским процессом через вызовы mlockall() или mlock().
  • Отображения памяти, созданные в родительском объекте, должны быть сохранены в дочернем процессе. Отображения MAP_PRIVATE, унаследованные от родителя, также должны быть отображениями MAP_PRIVATE в дочернем элементе, и любые изменения данных в этих отображениях, сделанные родителем до вызова fork(), должны быть видимы для дочернего элемента. Любые изменения данных в отображениях MAP_PRIVATE, сделанные родителем после возврата из fork(), должны быть видны только родителю. Изменения данных в отображениях MAP_PRIVATE, сделанные ребенком, должны быть видны только ребенку.
  • Для политик планирования SCHED_FIFO и SCHED_RR дочерний процесс должен наследовать настройки политики и приоритета родительского процесса во время функции fork(). Для других политик планирования параметры политики и приоритетов в fork() определяются реализацией.
  • Таймеры для процесса, созданные родителем, не должны наследоваться дочерним процессом.
  • Дочерний процесс должен иметь свою собственную копию дескрипторов очереди сообщений родительского процесса. Каждый из дескрипторов сообщений дочернего элемента должен ссылаться на то же самое описание открытой очереди сообщений, что и соответствующий дескриптор сообщения родителя.
  • Никакие асинхронные операции ввода или асинхронные операции вывода не должны наследоваться дочерним процессом.
  • Процесс должен быть создан с одним потоком. Если многопоточный процесс вызывает fork(), новый процесс должен содержать реплику вызывающего потока и всего его адресного пространства, возможно, включая состояния мьютексов и других ресурсов. Следовательно, чтобы избежать ошибок, дочерний процесс может выполнять только асинхронно-безопасные операции до тех пор, пока не будет вызвана одна из функций exec. Обработчики вил могут быть установлены с помощью функции pthread_atfork(), чтобы поддерживать инварианты приложения в вызовах fork(). Когда приложение вызывает fork() из обработчика сигнала, а любой из обработчиков вилки, зарегистрированных pthread_atfork(), вызывает функцию, которая не безопасна для asynch-signal, поведение не определено.
  • Если поддерживается опция Trace и опция Inceit Trace: если вызывающий процесс отслеживался в потоке трассировки, для которой его политика наследования была установлена ​​в POSIX_TRACE_INHERITED, дочерний процесс должен отслеживаться в этом потоке трассировки, а дочерний процесс должен наследовать Родительское сопоставление имен событий трассировки с идентификаторами типов трассировки. Если поток трассировки, в котором отслеживался вызывающий процесс, имел свою политику наследования, установленную на POSIX_TRACE_CLOSE_FOR_CHILD, дочерний процесс не должен отслеживаться в этом потоке трассировки. Политика наследования устанавливается путем вызова функции posix_trace_attr_setinherited().
  • Если опция Trace поддерживается, но опция Trace Inherit не поддерживается: дочерний процесс не должен отслеживаться ни в одном из потоков трассировки его родительского процесса.
  • Если опция Trace поддерживается, дочерний процесс процесса контроллера трассировки не должен контролировать потоки трассировки, контролируемые его родительским процессом.
  • Начальное значение времени ЦП дочернего процесса должно быть установлено равным нулю.
  • Начальное значение тактового времени процессора одного потока дочернего процесса должно быть установлено равным нулю. Все остальные характеристики процесса, определенные IEEE Std 1003.1-2001, должны быть одинаковыми в родительском и дочернем процессах. Наследование характеристик процесса, не определенных IEEE Std 1003.1-2001, не определено IEEE Std 1003.1-2001.
Другие вопросы по тегам