2014-12-10 3 views
3

매뉴얼 페이지에 따르면 select() 시스템 호출은 하나 이상의 파일 디스크립터의 3 가지 측면, 즉 읽을 준비가되어 있는지, 쓸 준비가되어 있는지, "오류"또는 "예외적 인 조건"(언어가 다양 함)가 발생했습니다. 이들 중 어느 것이 모니터 될지는 readfds, writefdserrorfds이라고하는 3 개의 fd_set 인수를 통해 지정됩니다. readfdswritefds의 올바른 사용법에 대한 좋은 설명서와 예제가 많이 있지만 errorfds에는 유용한 정보가 거의 없습니다.어떻게 "예외 조건"으로 인해 select()가 errorfds에 반응 했습니까?

아무튼, 아래에 설명 된 이유 때문에 나는 errorfds 시도를 사용했고 실제로 내 runloop에서 select() 호출이 파일 설명자 중 하나의 "예외 조건"에 응답 한 몇 가지 상황을 발견했습니다. 예를 들어 PTY에 연결된 TTY는 마스터 측에서 닫히고 PTY는 이러한 조건을 발생시킵니다.

하지만 이제 어떻게해야합니까? 나는 "예외적 인 조건"이 파일 기술자에서 발생했다는 것을 알고 있지만, 일반적으로 그것을 정확히 일으킨 원인을 어떻게 찾을 수 있습니까? errno을 보면 확실히 답을주지 못합니다 (그 시점에서 항상 0입니다). 아마도 내가 알아야 할 "마법의"일부 ioctl이 있습니까?

추가 배경 : 많은 프로그램 (대부분 C로 작성)은 직렬 포트를 통해 외부 하드웨어와 통신합니다. 테스트를 위해 다른 프로그램이 직렬 포트처럼 연결할 수있는 해당 TTY 인 PTY를 만드는 간단한 서버를 작성했습니다. 기본적인 수준에서 모든 것이 잘 작동하는 반면, 오류 또는 기타 예외적 인 조건의 처리는 현재 전혀 구현되지 않았으며 때로는 꽤 심한 행동으로 이어집니다. 이것은 변화해야합니다!

특히 감지에 관심이있는 하나의 예외적 인 조건은 연결이 끊어 졌는지 여부입니다. 예를 들어, 사용자가 USB 대 직렬 어댑터를 뽑았 기 때문에 포트가 사라 졌을 때 알아 차리는 것이 좋을 것입니다. 읽기 및 쓰기 오류를 적절히 처리하면 의도하지 않은 부작용이 가장 드문 것처럼 보이지 않지만 내가해야만하는 것이 더 있는지 (errorfds 또는 기타 신호가 있는지) 궁금해졌습니다. 유감스럽게도 유닉스 신호 처리는 제가 전혀 익숙하지 않은 무언가입니다.

+0

http://stackoverflow.com/questions/1342712/nix-select-and-exceptfds-errorfds-semantics – user3159253

+1

매우 휴대용 없음을 의미합니다 방금 지적한 다른 질문은 사실 내 것과 매우 비슷하다는 것을 알고 있습니다. 그러나 정확히 일치하는 것 같지 않았습니다.사실, 거기에 주어진 답변에서, "이 사용 사례에 대해 errorfds를 사용할 수 없다"는 것 이외에 내 질문에 대한 대답이 있는지 궁금하다. 그러나 계속 나아 가기 전에 확실히 알고 싶다. –

답변

1

"예외적 인 조건"이 파일 설명자에서 발생했음을 알고 있습니다. 그러나 일반적으로 어떻게 그 원인을 정확히 알 수 있습니까? 아마 내가 알아야 할 "마법의"ioctl이 있을까요?

0 바이트를 읽어야합니다. 리눅스에서 최소한 man 2 read 상태 :

count가 0이면, read()는 아래에 설명 된 오류를 감지 할 수 있습니다.

그래서, read(fd, NULL,0) 후 당신은 실제로 아무것도 읽을 필요없이, 당신에게 더 많은 것을 알려주는 errno이 있어야합니다. 맨 페이지의 족제비 단어 수도이는, 아마도하지만 (CF read(fd, NULL, 0); what does it do? is it well-defined?)

+0

더 안전하게하려면 할당 된 메모리에 유효한 포인터를 제공하고 0 바이트를 요청할 수 있습니다 :'char c; if (read (fd, & c, 0) <0) {... errno에 몇 가지 정보가 있습니다 ...}'. 그러나 함수 (시스템 호출)에 0 바이트를 전달할 때 여전히 EINVAL 오류가 발생할 수 있습니다. –

+0

@Jonathan : 예, 신뢰성이 높아야하지만 어쨌든 휴대용이 아니기 때문에 YMMV입니다. 시나리오에서 스티븐은 (깨어진 연결)에 관심이있다.'select()'는'errorfds'를 설정하지 않아도 어쨌든'SIGHUP '에 의해 인터럽트 될 것이다. 나는'SIGHUP'을 잡는 것이'read (fd, NULL, 0)'트릭보다 깨진 연결을 감지하는 더 이식 가능하고 신뢰할 수있는 방법이 될 것이라고 생각한다. –