Почему у / 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 . Почему это происходит?

  • Отправка сообщения от одного пользователя терминала другому пользователю
  • warning: Файловая система, похоже, смонтирована только для чтения
  • Как разрешить пользователю OpenLDAP записывать данные в точку монтирования SSHFS?
  • Как определить, записаны ли данные на диск или кэшированы?
  • Почему Debian предпочитает временный файл, заменяющий оригинал на изменение байтов в исходном файле?
  • One Solution collect form web for “Почему у / proc / self / fd / 0 нет бит записи в последовательном сеансе перед запуском оболочки?”

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

    Поэтому 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.

    Interesting Posts

    Как получить ширину границы окна X из командной строки?

    Как закрепить только файлы в нескольких подкаталогах?

    Aptitude – удалить все пакеты в категории X11, за исключением зависимостей определенного пакета

    Программа сжатия, показывающая коэффициент сжатия в реальном времени

    CentOS как xterminal

    медленная ссылка для загрузки с hostapd и драйвером ath9k_htc

    Ctrl + Delete и Ctrl + Backspace.

    Как получить n строк для каждой строки m (n <m) в командной строке?

    Как я могу убить программу, запущенную из rc.local, когда Ctrl-C не работает?

    Почему nautilus в фоновом режиме занимает столько IO и CPU при входе в систему, и как это разрешить, или это ошибка?

    У меньше есть функция типа tail –follow = name (-F)

    Как защитить от сканеров портов?

    Systemd: как запустить службу systemd после полной связи сети?

    chcon: не может применять частичный контекст к немеченому файлу при установке nagios с SELinux

    Приостановка процесса с помощью -SIGSTOP для достаточно длинных причин. Ядро Oops Stack Overflow

    Linux и Unix - лучшая ОС в мире.