Linux講座にようこそ。このページは「C言語プログラミング入門 - 第14章.ライブラリ関数 - その他のライブラリ」です。
ここで説明する関数を使うと、プログラムのどこへでも自由に分岐できます。便利な反面、プログラムが非常に理解しにくいものになってしまいますので、できるだけ使わない方がよいでしょう。
setjmp関数は非局所的なジャンプ用に実行環境(スタック・コンテキスト)を保存します。
形式 | #include <setjmp.h> int setjmp(jmp_buf env); |
---|---|
返り値 | 直接呼び出して実行した場合は0を返します。保存したスタック・コンテキストを使ってlongjmp関数を実行した場合はlongjmp関数で指定した値を返します。 |
引数 |
|
longjmp関数はsetjmp関数により保存した実行環境(スタック・コンテキスト)を使用して、非局所的なジャンプを行います。
形式 | #include <setjmp.h> void longjmp(jmp_buf env, int val); |
---|---|
返り値 | ありません。 |
引数 |
|
使用法、 他 |
setjmp関数により保存したスタック・コンテキストを復元することにより、実行ステップがsetjmp関数の直前に戻ります。このことにより、setjmp関数の直前にジャンプした状態になります。 |
実行時引数で指定したファイルの内容を標準出力に出力します。ただし、エラーが発生した場合はlongjmp関数によりエラー処理ステップに分岐して、メッセージを出力して終了します。
$ ls /etc/issue aaa.txt ls: cannot access aaa.txt: そのようなファイルやディレクトリはありません /etc/issue $ $ ./ex14_8_3.prg /etc/issue 環境を保存しました。 Fedora release 10 (Cambridge) Kernel \r on an \m (\l) $ echo $? 0 ← 正常終了です $ $ ./ex14_8_3.prg aaa.txt 環境を保存しました。 エラー発生の為、終了します。 $ echo $? 1 ← ファイルのオープンエラーです $ $ ./ex14_8_3.prg /etc/issue aaa.txt 環境を保存しました。 エラー発生の為、終了します。 $ echo $? 2 ← 実行時引数の指定エラーです $
シグナルには終了シグナルや、キーボードからの割り込みシグナルなどがあり、それぞれデフォルトの動作が設定されています。デフォルトの動作を変更する場合は、ここで説明するsignal関数でシグナル処理関数(シグナル・ハンドラ)を登録します。ただし、シグナル操作関数はシステムコールですので、処理系および、OSのバージョン等により動作が異なりますので使用する場合は注意してください。
なお、サポートしているシグナルの種類については、kill -l
コマンドで表示することが出来ます。
raise関数は引数で指定されたシグナルを送信します。
形式 | #include <signal.h> int raise(int signum); |
---|---|
返り値 | 正常に処理ができた場合は0を返します。エラーの場合は0以外を返します。 |
引数 |
|
シグナルは沢山あることやシステムにより異なる等のことから、ここに記述したものは代表的なもののみです。
シグナル | 値 | 意味 |
---|---|---|
SIGINT | 2 | キーボードからの割り込み(Interrupt)です。 |
SIGQUIT | 3 | キーボードによる中止(Quit)です。 |
SIGILL | 4 | 不正な命令です。 |
SIGABRT | 6 | abort関数からの中断(Abort)です。 |
SIGFPE | 8 | 浮動小数点例外です。 |
SIGUSR1 | 10 | ユーザ定義シグナル1です。 |
SIGSEGV | 11 | 不正なメモリ参照です。 |
SIGUSR2 | 12 | ユーザ定義シグナル2です。 |
SIGPIPE | 13 | パイプ破壊(読み手の無いパイプへの出力)です。 |
SIGALRM | 14 | alarmシステムコールからのタイマーシグナルです。 |
SIGTERM | 15 | 終了(Termination)です。 |
SIGCHLD | 17 | 子プロセスの一旦停止(Stop)または終了です。 |
SIGCONT | 18 | 一旦停止(Stop)からの再開です。 |
SIGTSTP | 20 | 端末(tty)から入力された一旦停止(Stop)です。 |
SIGTTIN | 21 | バックグランドプロセスのtty入力です。 |
SIGTTOU | 22 | バックグランドプロセスのtty出力です。 |
signal関数は指定されたシグナルに対応する、シグナル処理関数(シグナル・ハンドラ)を登録します。シグナル・ハンドラを実行すると、登録はリセットされますので同じ処理を行いたい場合は再度登録する必要があります。また、SIGKILL(強制終了)とSIGSTOP(一旦停止)シグナルは捕捉できませんし、無視することもできません。
形式 | #include <signal.h> void ( *signal(int signum, void (*handler)(int)) ) (int); |
---|---|
返り値 | 登録されていたシグナル・ハンドラの値を返します。エラーの場合はSIG_ERRを返します。 |
引数 |
|
SIGQUITシグナルを受信するまで「実行中!!」メッセージを表示し続けます。また、SIGINTシグナルを受信すると終了確認メッセージを出力し、「y」を入力すると終了し、それ以外を入力すると処理を続行します。なお、SIGQUITはコントロール(Ctrl)キーと「C」キーを同時に押し、SIGINTはコントロール(Ctrl)キーと「\」キーを同時に押します。
$ ./ex14_8_4.prg 実行中!! 実行中!! 実行中!! ^\割り込みを受け付けました。 ← SIGQUITシグナル発行 直ちに終了します。 $ $ ./ex14_8_4.prg 実行中!! 実行中!! ^C割り込みを受け付けました。 ← SIGINTシグナル発行 終了しますか?(Y/N)==> n 実行中!! 実行中!! 実行中!! ^C割り込みを受け付けました。 ← SIGINTシグナル発行 終了しますか?(Y/N)==> n 実行中!! 実行中!! 実行中!! 実行中!! ^C割り込みを受け付けました。 ← SIGINTシグナル発行 終了しますか?(Y/N)==> y 直ちに終了します。 $