Intereting Posts
Не удается установить rsync (невозможно создать … Ошибка ввода / вывода) Можно ли установить сеанс Socket (между сервером и клиентом) с помощью команд оболочки? NetworkManager: отключена сеть при отправке системы в режим сна Как определить количество страниц документов djvu из CLI? Как установить LXDE и X Window System на Debian Squeeze Обход фрагмента nawk, если входной файл пуст Fedora 17: Nautilus, после монтирования вручную, устройство больше не увидит в разделе «Устройство» Как заставить бесконечно исполняющуюся команду убивать себя, когда выполняются определенные условия? Как использовать awk для подсчета общего количества строк ввода в файле? Смутно о поведении звездочки в команде ls Сбой командной строки при использовании дерева каталогов / имени файла Как распечатать список vim для файла в формате ? Сборка собственного ядра с отключенным kswapd0 Как использовать sed с круглыми скобками? pam_tacplus.so и sshd: пропустить проверку пользователя?

Почему у / proc / self / fd / 0 нет бит записи в последовательном сеансе перед запуском оболочки?

Я наткнулся на программу, которая использует очень старую версию библиотеки linenoise . Все write() выполняются для STDIN_FILENO , например:

 write(STDIN_FILENO,prompt,plen) 

write не выполняется с -1 и errno устанавливается в EBADF . Я написал программу C, которая запускается в конце /etc/init.d/rcS которая, в свою очередь, выполняется Busybox init при загрузке системы до Busybox init интерактивного sh . Программа C перечисляет каталог /proc/self/fd , ее выход:

 l-wx------ 1 root root 64 Jan 1 00:00 2 -> /dev/console l-wx------ 1 root root 64 Jan 1 00:00 1 -> /dev/console lr-x------ 1 root root 64 Jan 1 00:00 0 -> /dev/console 

Как вы видите, 0 не имеет бит бит, и я думаю, что поэтому write не выполняется. Однако после запуска обычной оболочки sh :

 lrwx------ 1 root root 64 Jan 1 00:00 2 -> /dev/ttyS0 lrwx------ 1 root root 64 Jan 1 00:00 1 -> /dev/ttyS0 lrwx------ 1 root root 64 Jan 1 00:00 0 -> /dev/ttyS0 

Теперь 0 имеет w . Почему это происходит?

Потому что вы можете иметь несколько терминальных устройств.

Поэтому getty вызывается с ttyS0 специально, как параметр. Поэтому он использует свой собственный код для инициализации всех FD. Это происходит, по-другому, с кодом ядра, который открывает /dev/console для init . Можно догадаться, что getty открывает tty один раз O_RDWR , а затем дублирует FD.

Я вижу одну очевидную причину, по которой этот код работает. agetty также можно вызвать с помощью значения stdin. Поэтому всегда использование dup() – это простейшая реализация.

Я не уверен, почему этот вариант был поддержан. Он не обязательно используется или поддерживается в стандартной системе V inittab . Он, похоже, соответствует более старым подходам, используемым в BSD , где init передает терминальное устройство в качестве открытого FD вместо параметра. Более старый подход заключается в инициализации всех FD ( ссылка , обратите внимание только на 2 FDs, поскольку stderr был добавлен в следующую версию ).

Поскольку вопрос был отредактирован, чтобы указать busybox, и был указан cttyhack, очевидное объяснение в случае busybox – «он сохраняет код меньше». Это было также движущей особенностью исторического кода unix.