올바른 진술은 어느 것입니까?
모든 Unix 프로세스는 표준 입력, 표준 출력 및 표준 오류와 같은 표준 파일 설명자를 엽니다.
또는
터미널에 연결된 모든 Unix 프로세스는 표준 입력, 표준 출력 및 표준 오류와 같은 표준 파일 설명자를 엽니다.
답변1
그들은 모두 틀렸습니다.
sleep 999 <&- >&- 2>&-
^C
Unix 프로세스에는 sleep 999
표준 파일 설명자가 열려 있지 않지만 Control-C를 사용하여 종료할 수 있으므로 여전히 터미널에 연결되어 있습니다.
답변2
객관식 질문인 경우 첫 번째 질문을 확인하세요. 교사는 이러한 표준 파일 설명자가대개터미널에 연결된 프로세스뿐만 아니라 모든 프로세스에 열려 있습니다.
그러나 시작 시 첫 번째 프로세스 외에는 어떤 프로세스도 이러한 시작을 통과한다고 절대적으로 보장되지 않습니다. 두 번째 진술이 더 정확하다고 주장할 수 있습니다. 왜냐하면 이것이 열리지 않으면 더 이상 실제로 터미널에 연결되지 않기 때문입니다(논쟁의 여지가 있음).
사실은 무엇입니까?
모든 프로세스가 허용됩니다폐쇄()또는 STDIN STDOUT STDERR을 포함한 파일 설명자를 바꾸십시오. 일단 닫히면, 그들은 할 것입니다사라졌다그리고 더 이상 FD로 존재하지 않습니다. 하위 프로세스가 보유한 모든 파일 설명자는 상위 프로세스에서 상속됩니다. 따라서 프로세스가 이러한 세 가지 표준 파일 설명자를 닫은 다음 하위 프로세스를 생성하면 하위 프로세스도 해당 파일 설명자를 소유하지 않습니다.
분명히 말하면 이것은 잘못된 것입니다.
따라서 프로세스 생성 시스템 호출은 세 가지 표준 파일 설명자를 사용하여 모든 프로세스를 생성하지만 일부 프로세스는 터미널에서 분리됩니다.
상위 프로세스가 설명자를 교체하지 않고 닫아 터미널에서 분리되는 경우dup2(), 아이는 그것을 갖지 않을 것입니다. 그 아이가 자신의 아이를 만들었다면, "손자"도 그 아이를 갖지 못할 것입니다…
이에 대한 posix 참조를 위해서는 프로그램 실행이 일반적으로 다음 조합으로 수행된다는 점을 이해해야 합니다.
fork()
자식 프로세스 시작execve()
하위 프로세스에서 다른 프로그램 실행
POSIX에 따르면fork()는 모든 파일 설명자를 상속합니다.
하위 프로세스에는 상위 프로세스의 파일 설명자에 대한 자체 복사본이 있어야 합니다. 각 하위 항목의 파일 설명자는 상위 항목의 해당 파일 설명자와 동일한 열린 파일 설명을 참조해야 합니다.
넘어질 위험이 더 있습니다. 일부 파일 설명자는 호출 시 자동으로 닫히도록 설정할 수 있습니다.구현하다():
호출 프로세스 이미지에서 열린 파일 설명자는 실행 닫기 플래그 FD_CLOEXEC가 설정된 파일 설명자를 제외하고 새 프로세스 이미지에서 열린 상태로 유지됩니다.
따라서 상위 프로그램이 파일 설명자를 명시적으로 닫지 않더라도 하위 프로그램에 대한 파일 설명자가 존재하지 않을 수 있습니다.
답변3
모든 적대적인 댓글에 대해 다음과 같은 답변을 제안합니다.
여기에는 POSIX 표준에 대한 링크가 포함되어 있습니다.
https://pubs.opengroup.org/onlinepubs/009695399/functions/stdin.html
프로그램 시작 시 세 가지 스트림이 미리 정의되어야 하며 명시적으로 열 필요가 없습니다. 표준 입력(일반 입력 읽기용), 표준 출력(일반 출력 쓰기용) 및 표준 오류(진단 출력 쓰기용). 열릴 때 표준 오류 스트림은 완전히 버퍼링되지 않습니다. 표준 입력 및 표준 출력 스트림은 표준 입력 및 표준 출력 스트림이 대화형 장치를 참조하지 않는다고 판단할 수 있는 경우에만 완전히 버퍼링됩니다.