UNIX® および関連オペレーティング・システムに関する特別な考慮事項
システム呼び出しの中には、open、read、write、close、ioctl、pause などのシグナルをプロセスが受け取ると、失敗するものがあります。
関数がこれらのシステム呼び出しを使用する場合、実際のエラー、Ctrl-C、および再起動を必要とする呼び出しを区別できるように、注意してコードを記述する必要があります。生成された小規模な関数セットにより、非同期イベントのチェックや、$ZF に新規のアラーム・ハンドラを設定できます。
その他のコールアウト・シグナル処理
関数の宣言は、cdzf.h に組み込まれます。
-
int sigrtclr(); — 再試行フラグを消去します。sigrtchk() を使用する前に一度呼び出す必要があります。
-
int dzfalarm(); — 新規 SIGALRM ハンドラを構築します。
$ZF にエントリする際に、前のハンドラが自動的に保存されます。終了すると、自動的にリストアされます。ユーザ・プログラムで、他のシグナル処理を変更しないでください。
-
int sigrtchk(); — 非同期イベントをチェックします。これは、open、close、read、write、ioctl、または pause のいずれかのシステム呼び出しが失敗した場合や、プロセスがシグナルを受け取ったときに失敗する呼び出しがある場合に、必ず呼び出す必要があります。ユーザの次の動作を示すコードを返します。
-
-1 — シグナルではありません。入出力エラーを調べてください。errno 変数の内容を参照してください。
-
0 — 他のシグナルです。割り込みが生じた時点から処理を再開してください。
-
1 — SIGINT/SIGTERM。SIGTERM "return 0" で $ZF を終了します。これらのシグナルは適切にトラップされます。
-
一部のデバイスの制御に使用される一般的な $ZF 関数は、以下の擬似コードと同様のロジックを使用します。
if ((fd = open(DEV_NAME, DEV_MODE)) < 0) {
Set some flags
Call zferror
return 0;
}
プロセスがシグナルを受け取ると、open システム呼び出しは失敗する可能性があります。通常、これはエラーではないため、処理を再開できます。しかし、シグナルによっては他の処理が必要な場合もあります。すべての可能性を考慮するために、以下の C コードを使用することを検討してください。
sigrtclr();
while (TRUE) {
if (sigrtchk() == 1) return 1 or 0;
if ((fd = open(DEV_NAME, DEV_MODE)) < 0) {
switch (sigrtchk()) {
case -1:
/* This is probably a real device error */
Set some flags
Call zferror
return 0;
case 0:
/* A innocuous signal was received. Restart. */
continue;
case 1:
/* Someone is trying to terminate the job. */
Do cleanup work
return 1 or 0;
}
}
else break;
}
/*
Code to handle the normal situation:
open() system call succeeded
*/
dzfalarm 経由の場合を除き、シグナル・ハンドラを設定してはいけません。