私は小さなアプリケーションを書いており、できるだけ移植可能にしたいと思います(Linux、* BSD、およびその他のUNIX)。私の主な問題は管理ですEINTR
。一部のシステムにはEINTR
文書化されていないが返すことができるシステムコールがあることがわかりました(例:stat(2)
Linuxで)。そうですか?
EINTR
現在の回避策は、このエラーを返さないと記録されていても、すべてのシステムコールでラッパーを使用して再試行することです。すべての「POSIX互換」システムで安全ですか?このアプローチを使用すると、どのような問題が発生する可能性がありますか?本当に推奨/必須ですか?
答え1
一部のシステムの一部のシステム呼び出しは、EINTRを返す可能性があることを読みました。たとえ文書化されていませんが(例:Linuxのstat(2))。そうですか?
すべての信号をブロックしない限り、I / Oをブロックできるすべてのシステムコールを返すことができますEINTR
。これはカーネルの一般的な動作であるため、これらのシステムコールごとに繰り返し文書化されていないのが合理的です。また、重複した文書を探したくありません。EIO
同じ理由で、すべてのI/Oシステムコールで。
もっと広く言えば、Linuxのmanページは返すことができるエラーの完全なリストを提供しません。上記の状況だけでなく、カーネルには多くのレイヤがありますが、各syscalの役割は何ですか?できる報酬は、どのドライバーが参加するかなどによって異なります。 XFSファイルシステムのファイルを参照するときに-1が返された場合、errno
-1が返されたときに可能な値のセットは、read(2)
FIFOを参照するときとは異なります。fd
マニュアルページで可能なすべてのエラー戻りコードを提供すると期待するのは無理です。errno(3)
もしそうなら。
このアプローチを使用すると、どのような問題が発生する可能性がありますか?本当に推奨/必須ですか?
盲目的にシステムコールを再起動することは、アプリケーションの正しいアプローチではないかもしれません。システムコールリターンは、EINTR
アプリケーションがシグナルハンドラのコンテキストではなくコールコンテキストでシグナルを処理する機会を提供します。たとえば、これはグローバル変数を防ぐのに役立ちます。
この問題の1つの観点については、次を参照してください。EINTR
その利点は何ですか。
また、sigaction
その記事で指摘した事項に注意してください。以下を使用してこの動作を制御できます。SA_RESTART
。次の質問がこのフラグを1に設定するのか、0に設定する必要があるのかを尋ねる場合、答えはアプリケーションによって異なります。