2017-11-13 16 views
0

私はLinux用の簡単な文字デバイスドライバを書いています。charデバイスドライバを "cat"しようとすると、エラーメッセージが表示されるのはなぜですか?

メッセージがカーネル空間に格納されるシンプルなメッセージ格納/検索システムです。

echo "message 1" > /dev/mydevice 

をして、メッセージがキューに格納されている

cat /dev/mydevice 

でメッセージを取得:

私はこのような何かを行うことができるはず。

私は(メッセージが「こんにちは」である)私は、ハードテストのためでコード化されたメッセージを取得しようとすると、私は次のコマンドライン出力を得る:

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

意図したとおりだから私は、helloメッセージを取得しかし、明らかに私はかなり正しくないことをしています。

ここでは、デバイスの読み取りを処理する関数があります。それは(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 "'の後に空のメッセージをハードコーディングし、それが動作するかどうか確認してください。これが実際の問題であれば、おそらく最良の解決策ではないかもしれませんが、テストするのは簡単ですが、1つのメッセージをスレッドセーフな方法で各リーダーに正確に返すことは難しいでしょう) –

+0

メッセージがなくなったときにEAGAINを返すことは、私の割り当ての要件の一部です。私は、私がEOFのために0を返す必要があることを考えれば、これをどのように克服することができるかについて少し混乱しています。 – toastedDeli

+0

@DanielHまた、それは猫が私の読み取り機能を複数回呼び出すことを意味するのでしょうか?私は伝統的に読み込みバイト数を返すと思った。 – toastedDeli

答えて

3

catユーティリティは、ファイルごとに何度もread以上を呼び出します。

これは、すべてのデータがすぐに利用できるわけではないためです。ファイルがcatの内部バッファより大きい場合は、もちろん完全なデータを取得するためにreadを何度も呼び出す必要があります。 readによって返されたバイト数がバッファの長さよりも短かったとしても、入力がTTYまたはパイプの場合のように、後でさらにデータが利用できる場合は、readを再度呼び出す必要があります。したがって、catにファイルの最後にあると思って読み込みを停止させるには、0を返す必要があります。

(どのようcat作品についての詳細は、あなたがthe source code、およびsafe_read functionを確認することができます。)

これを処理する簡単な方法は、それぞれの「本物」の後に、あなたのキューにゼロ長のメッセージを入れることであろう次のreadはEOFを返します。ただし、同時に複数の読者がいる場合、これは正しく機能しません。その場合、1人の読者がメッセージを読んでから、もう1人がEOFを読んだ後、最初の読者が別のメッセージを読んで、一方の読者が2つのメッセージを得、もう一方の読者がゼロになる。あなたのデバイスがスレッドセーフであるかどうかは、あなたやあなたのインストラクタに任されます.¹

これはまた、部分的にしか扱わないコードの別の潜在的な問題を示します。readに渡されたバッファより大きいメッセージ次のメッセージのために保存する代わりに残りのメッセージを破棄します。read。再び、これは容認できる短命化であるかもしれないし、そうでないかもしれない。


¹スレッドセーフにすることが可能かどうかわかりません。それはあなたがいろいろな読者をいかにうまく区別できるかにかかっています。カーネルコードやキャラクターデバイスを書くことが可能かどうかは十分に分かりません。

関連する問題