2017-11-13 5 views
0

Linux 용 문자 장치 드라이버를 작성했습니다.char 장치 드라이버를 "cat"하려고 할 때 오류 메시지가 나타나는 이유는 무엇입니까?

메시지가 커널 공간에 저장되는 간단한 메시지 저장/검색 시스템입니다.

echo "message 1" > /dev/mydevice 

을 다음 메시지는 큐에 저장됩니다

cat /dev/mydevice 

으로 메시지를 검색 :

나는 같은 것을 할 수 있어야합니다.

나는 하드 (메시지가 "안녕하세요"입니다), 나는 다음과 같은 명령 줄 출력을 얻을 테스트에서 코딩 된 메시지를 검색 할 때 :

cat /dev/mydevice 
hellocat: /dev/mydevice: Resource temporarily unavailable 

그래서 나는 헬로 메시지가 의도대로를 , 그러나 분명히 내가 옳지 않은 것을하고있다.

여기에는 장치 읽기를 처리하는 함수가 있습니다. 이 (signified by read returning 0 인) EOF에 도달 할 때까지

static ssize_t device_read(struct file *filp, char *buffer, 
       size_t length, loff_t * offset) { 
    unsigned long result; 
    int message_size; 
    struct message_list* message = pop_message(&global_message_list); 

    if (!message) return -EAGAIN; 

    message_size = message -> message_length; 

    result = copy_to_user(buffer, message -> message, message_size); 

    printk(KERN_ALERT "res: %lu, msg_size: %d, len: %d\n", result, message_size, length); 
    if (result == 0) return message_size; 
    else return message_size - result; 
} 
+0

'cat'은 EOF에 도달 할 때까지 계속 읽으 려한다고 생각합니다 ('read'는 0을 반환합니다). 이 경우 메시지가 없어지면 즉시 'EAGAIN'으로 이동합니다.대기열에있는 "hello"뒤에 빈 메시지를 하드 코딩 해보고 그 메시지가 제대로 작동하는지 확인하십시오. (이것이 실제로 문제가된다면 아마도 가장 좋은 해결책은 아니지만 테스트하기가 더 쉽습니다. 한 가지 방법으로 thread-safe 방식으로 정확히 하나의 메시지를 각 리더에 반환하는 것은 어려울 것입니다.) –

+0

더 이상 메시지가 없을 때 EAGAIN을 반환하는 것은 내 과제에 대한 요구 사항의 일부입니다. 나는 EOF를 위해 0을 반환 할 필요가 있음을 감안할 때이 점을 어떻게 극복 할 수 있을지 조금 혼란 스럽다. – toastedDeli

+0

@DanielH 또한 고양이가 내 읽기 기능을 여러 번 부르는 것을 의미합니까? 나는 전통적으로 읽은 바이트 수를 반환했다고 생각했다. – toastedDeli

답변

3

cat 유틸리티는 각 파일에 대해 한 번 이상 read 더를 호출합니다.

모든 데이터가 즉시 제공되지 않을 수 있기 때문입니다. 파일이 내부 버퍼 인 보다 큰 경우 전체 데이터를 얻으려면 read 번을 여러 번 호출해야합니다. read에 의해 반환 된 바이트 수가 버퍼 길이보다 작더라도 나중에 더 많은 데이터를 사용할 수 있도록하려면 read을 다시 호출해야합니다 (입력이 TTY 또는 파이프 인 경우). 따라서 cat이 파일의 끝에 있다고 생각하고 읽기를 중지하려면 0을 반환해야합니다.

(방법 cat 작품에 대한 자세한 내용 들어, the source code하고 safe_read function을 확인할 수 있습니다.)

이 각각 "진짜"후 큐에 길이 제로의 메시지를 넣어하는 것입니다 처리하는 간단한 방법 다음 read은 EOF를 반환합니다. 그러나 동시에 여러 독자가있는 경우이 작동하지 않습니다. 이 경우 하나의 판독기가 메시지를 읽은 다음 다른 하나는 EOF를 읽은 다음 첫 번째 판독기가 다른 메시지를 읽음으로써 하나의 판독기가 두 개의 메시지를 얻고 다른 하나는 0이됩니다. ¹

이는 부분적으로 만 처리 할 수있는 코드의 또 다른 잠재적 인 문제를 나타냅니다. read으로 전달 된 버퍼보다 ​​큰 메시지가있는 경우에도이 문제는 귀하 및/또는 강사에게 달려 있습니다. 나머지 메시지는 다음 read에 저장하는 대신 삭제합니다. 다시 말하지만, 이것은 받아 들일 수있는 단식이거나 그렇지 않을 수 있습니다.


¹ 스레드 세이프가 가능한지 확실하지 않습니다. 그것은 다른 독자를 얼마나 잘 구별 할 수 있는지에 달려 있습니다. 커널 코드에 대해 충분히 알지 못하거나 가능한 문자 코드를 쓰고 있습니다.