web-dev-qa-db-ja.com

errno!= EINTRかどうかの確認:どういう意味ですか?

私はこのコードの一部が数回使用されていることを発見しました(open()の代わりにwrite()を使用した場合も同様です)。

int c = write(fd, &v, sizeof(v));
if (c == -1 && errno != EINTR) {
    perror("Write to output file");
    exit(EXIT_FAILURE);
}

&& errno != EINTRここ?

manerrnoを探していますEINTRに関する次のテキストが見つかりましたが、man 7 signalそれは私を啓発しません。

EINTR割り込み関数呼び出し(POSIX.1); signal(7)を参照してください。

17
Robb1

システムコールの進行中に信号が発生した場合、多くのシステムコールはEINTRエラーコードを報告します。エラーは実際には発生していません。システムがシステムコールを自動的に再開できないため、そのように報告されます。このコーディングパターンは、これが発生したときにシステムコールを再試行するだけで、割り込みを無視します。

たとえば、タイマーが切れたときにプログラムがalarm()を使用してコードを非同期に実行すると、これが発生する可能性があります。プログラムがwrite()を呼び出している間にタイムアウトが発生した場合は、システムコール(別名:読み取り/書き込みなど)を再試行するだけです。

28
Barmar

ここでの答えは本当に良いです、そして私はいくつかの内部の詳細を追加したいと思います:

シグナルによって中断されたシステムコールは、sigaction(2)SA_RESTARTが指定されている場合にのみ、中止してEINTRを返すか、自動的に再起動します。

このタスクを担当するのはrestart_blockであり、システムコールを再起動するための情報と引数を追跡するために使用されていました

3
zerocool

writeの-​​ man page から:

データが書き込まれる前に、呼び出しがシグナルによって中断されました

2
Kevin