2014-02-06 3 views
0

일반 파일 작업에 대한 래퍼를 쓰고 있으며 쓰기가 제공된 다음 작은 크기를 반환 할 때이 문제를 처리하는 방법을 알지 못합니다.쓰기가 더 작은 크기를 반환하면 어떻게해야합니까?

쓰기에 대한 man 페이지는 말한다 :

예를 들어,이 기본 물리적 매체에 공간이 부족, 또는 RLIMIT_FSIZE 자원 제한이며, 경우 수보다 적을 수 있습니다 기록 된 바이트의 수 (countrlimit (2)를 참조), count보다 작은 바이트를 쓴 후에 시그널 핸들러에 의해 호출이 인터럽트되었다. (파이프 (7)도 참조하십시오.)

위의 내용을 이해하면 오류 (중간 정도)와 다시 돌아온 (중단 된 호출)이 혼합 된 것입니다. 내 파일 디스크립터가 모두 비 블로킹이라면 인터럽트 케이스를 얻지 않아야하며 오류가 유일한 원인이된다. 내가 맞습니까?

코드 예제 :

int size_written = write(fd, str, count); 
if (size_written == -1) { 
    if (errno == EAGAIN) { 
    // poll on fd and come back later 
    } else { 
    // throw an error 
    } 
} else if (size_written < count) { 
    // *************** 
    // what should I do here ? 
    // throw an error ? 
    // *************** 
} 
당신은 루프에서 원시 I/O 기능을 사용할 필요가

답변

2

는 :

ssize_t todo = count; 

for (ssize_t n; todo > 0;) 
{ 
    n = write(fd, str, todo); 
    if (n == -1 && errno != EINTR) 
    { 
     // error 
     break; 
    } 
    str += n; 
    todo -= n; 
} 

if (todo != 0) { /* error */ } 

EINTR에 관한 특별한 조건은 쓰기 호출이 될 수 있습니다 전체 작동이 실패하지 않으면 서 신호에 의해 중단됩니다. 그렇지 않으면 결국 모든 데이터를 쓸 수있을 것으로 기대합니다.

파일 설명자가 비 블로킹이고 현재 어떤 데이터도 받아 들일 수 없기 때문에 모든 데이터 작성을 완료 할 수없는 경우 나머지 데이터를 저장하고 파일 설명자가 준비가되었음을 알리면 나중에 다시 시도해야합니다 다시 쓰기 위해.

+0

설명해 주셔서 감사합니다. 나는 약간의 변화가 있어야한다고 생각한다. (ssize_t n; todo;) – gaspard

+0

@GaspardBucher : 예, 정말로 고마워요! –