3

내 프로그램에서 호출 나는 재 시도한다.시스템 호출의 반환 값과 errno를

예 : 여기

recvagain:  
    len = recvfrom(fd, response, MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen); 
    if (errno == EINTR) { 
      syslog(LOG_NOTICE, "recvfrom interrupted: %s", strerror(errno)); 
      goto recvagain; 
    } 

문제는 내가 0에 실패 각각의 모든 시간의 errno 값을 다시 설정해야 할 것입니다. 또는 recvfrom()이 성공적이면 errno를 0으로 재설정합니까?

에 recvfrom() 매뉴얼 페이지는 말한다 :

성공적으로 완료되면

,에 recvfrom()가 바이트 메시지의 길이를 반환합니다. 메시지를받을 수없고 수신자가 피어가 정상 종료를 수행 한 경우 recvfrom()은 0을 반환합니다. 그렇지 않으면이 함수는 -1을 반환하고 오류를 나타내는 errno를 설정합니다.

sendto 및 sendmsg와 동일한 경우.

서버 클라이언트 설정에 액세스 할 수 없으므로 지금은 이것을 확인할 수 없습니다. 아이디어가 있으십니까?

감사가 중단 (및 errnoEINTR에 설정) 경우

답변

4

errno 의사 "변수"성공적인 콜에 변경할 수 없습니다. 따라서 recvfrom 전에 또는 len<0을 테스트하고 값을 테스트 한 후에이 값을 지울 수 있습니다.

자세한 내용은 errno(3) 매뉴얼 페이지를 참조하십시오.

실제로 로버트 샤오 (nneonneo)가 말한대로 errno을 쓰지 말고 syscall이 실패했을 때 테스트해야합니다 (이 경우 C 함수 -eg recvfrom 등 ... - syscall이 작성한 errno) -1을 반환합니다.

+2

'errno'를 지울 필요가 거의 없습니다; 나는 이것이 그 시대의 하나라고 생각하지 않는다. – nneonneo

+0

'errno '를 지우는 남자의 이유는 이전에 관련이없는 시스템 콜에 의해 (이전에) 설정되었을 때를 커버하기위한 것입니다. –

+1

일반적으로 신경 쓰지 않아야합니다. 내 답변에서 지적한 바와 같이 올바른 해결책은 'len'을 검사하여 오류가 실제로 발생했는지 확인하는 것입니다. – nneonneo

7

recvfrom 반환 -1. 따라서, 당신은 단지 len를 확인해야합니다 :

if(len == -1) { 
    if(errno == EINTR) { 
     syslog(LOG_NOTICE, "recvfrom interrupted"); 
     goto recvagain; 
    } else { 
     /* some other error occurred... */ 
    } 
} 
+0

좋아, 내가 할거야, 그리고 어때? 시스템 콜이 성공하면 다시 초기화되지 않는다는 것을 의미합니까? – Ram

+9

'errno'는 함수가 오류를 나타내는 값을 반환 한 경우에만 신뢰할 수 있습니다. 그렇지 않으면 무의미 할 수 있습니다. –