아주 오래된 버전을 사용하고 있는 프로그램을 발견했습니다라인 노이즈도서관. 다음과 같이 모든 write()
작업이 완료되었습니다 STDIN_FILENO
.
write(STDIN_FILENO,prompt,plen)
write
실패하고 -1을 반환하며 errno
로 설정됩니다 EBADF
. 대화식으로 시작하기 전에 시스템이 시작될 때 순차적으로 실행되는 C 프로그램을 작성했습니다 /etc/init.d/rcS
. C 프로그램은 디렉토리를 나열하고 출력은 다음과 같습니다.Busybox init
sh
/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 비트가 w
설정되지 않았으므로 이것이 실패하는 것 같습니다 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
설정되었습니다. 왜 이런 일이 발생합니까?
답변1
여러 개의 터미널 장치를 가질 수 있기 때문입니다.
따라서 getty
구체적으로 매개변수라고 합니다. ttyS0
따라서 자체 코드를 사용하여 모든 FD를 초기화합니다. 이는 tty를 한 번 연 /dev/console
다음 FD 를 참조하는 것과 같습니다 .init
getty
O_RDWR
dup
분명한 이유가 보이네요암호다음과 같이 작동합니다. stdin을 사용하여 호출 agetty
할 수도 있습니다 . -
따라서 항상 사용하는 것이 dup()
가장 간단한 구현입니다.
이 옵션이 왜 지원되는지 잘 모르겠습니다. 표준 시스템 V는 반드시 이를 사용하거나 지원하지는 않습니다 inittab
. 와 일치하는 것 같다BSD에서 사용되는 이전 방법여기서 init
터미널 장치는 매개변수 대신 열린 FD로 전달됩니다. 기존 방식은 init
모든 FD를 초기화하는 것이었습니다(협회stderr
, 다음 버전에 추가된 2개의 FD를 참고하세요 ).
busybox를 지정하도록 질문을 편집했고 cttyhack이 언급되었으므로 busybox의 경우 분명한 설명은 "코드를 더 작게 만듭니다"입니다. 이는 또한 역사적인 Unix 코드의 주요 특징이기도 합니다.