Хорошей отправной точкой является статья "Небольшой след в ядре Linux" от 2001 года. Механизмы все еще схожи, хотя реализация продвинулась и лучше всего изучена в последнее ядро .
Внутри ядра каждый дескриптор открытого файла соответствует struct file
, который содержит всю информацию об открытом файле или устройстве.Файловый дескриптор на самом деле не более, чем указатель на FDT для процесса.В ядре Linux struct file
присоединяется к FDT функцией fd_install()
.struct file
может быть переназначен другому дескриптору файла с помощью системного вызова dup2
.
Процессы могут использовать один и тот же FDT, если процессы были созданы системным вызовом clone
сфлаг CLONE_FILES
, но глобальный FDT отсутствует.Обычная операция fork
создает новый FDT, который является копией родительского FDT.Практическое использование этого для того, чтобы каждый поток многопоточного приложения был клонированным процессом с общим FDT, гарантируя, что все потоки могут использовать одинаковые целочисленные файловые дескрипторы.Если вы создаете новый процесс, используя fork
/ exec
, новый процесс запускается с теми же файловыми дескрипторами, но может открывать и закрывать файлы, не затрагивая родительский процесс.
Записи FDT для stdin, stdout, stderrнаследуются от родителя.В их реализации этих трех записей FDT нет ничего особенного;их значение происходит от обычного использования библиотекой C.Только родительский процесс решает, с чем он связан.Они могут подключаться к символьным устройствам или подключаться к файлам или каналам.Для случая символьного устройства наиболее нормальным является tty или pty устройство.Бесплатная книга Драйверы устройств Linux содержит хороший обзор из них.