私はこのコードの一部が数回使用されていることを発見しました(open()
の代わりにwrite()
を使用した場合も同様です)。
int c = write(fd, &v, sizeof(v));
if (c == -1 && errno != EINTR) {
perror("Write to output file");
exit(EXIT_FAILURE);
}
&& errno != EINTR
ここ?
manでerrno
を探していますEINTR
に関する次のテキストが見つかりましたが、man 7 signal
それは私を啓発しません。
EINTR割り込み関数呼び出し(POSIX.1); signal(7)を参照してください。
システムコールの進行中に信号が発生した場合、多くのシステムコールはEINTR
エラーコードを報告します。エラーは実際には発生していません。システムがシステムコールを自動的に再開できないため、そのように報告されます。このコーディングパターンは、これが発生したときにシステムコールを再試行するだけで、割り込みを無視します。
たとえば、タイマーが切れたときにプログラムがalarm()
を使用してコードを非同期に実行すると、これが発生する可能性があります。プログラムがwrite()
を呼び出している間にタイムアウトが発生した場合は、システムコール(別名:読み取り/書き込みなど)を再試行するだけです。
ここでの答えは本当に良いです、そして私はいくつかの内部の詳細を追加したいと思います:
シグナルによって中断されたシステムコールは、
sigaction(2)
でSA_RESTART
が指定されている場合にのみ、中止してEINTR
を返すか、自動的に再起動します。
このタスクを担当するのはrestart_block
であり、システムコールを再起動するための情報と引数を追跡するために使用されていました
write
の- man page から:
データが書き込まれる前に、呼び出しがシグナルによって中断されました