システムプログラム 練習問題 #5

練習問題(501)

kill システムコールでシグナルを送るプログラムとシグナルを受け取るプログラムを使用して,プロセスからプロセスへシグナルが送られるのを確かめなさい.

ヒント: 端末ウィンドウを2つ開き,片方のウィンドウでシグナルを受け取るプログラムを動かし,もう片方のウィンドウでシグナルを送るプログラムを動かす. シグナルを受け取るプロセスのIDは ps コマンドで調べるか,シグナルを受け取るプログラムを変更して自分のプロセスIDを表示させるようにする.

練習問題(502)

複数の異なるシグナルに対してシグナルハンドラを設定し,シグナルに応じたシグナルハンドラが起動されることを確かめなさい.

ヒント: シグナルは様々な方法で発生させることができる. kill コマンドや kill システムコールを使えば,好きなシグナルを好きなプロセスに送信することができる. キー入力や GUI 操作でシグナルを発生させることもできる. 例えば Ctrl-z を入力すると SIGTSTP を発生させることができ,端末のウィンドウのサイズを変えると SIGWINCH を発生させることができる.

練習問題(503)

不正なメモリアクセスは SIGSEGV により通知される. 不正なメモリアクセスを意図的に行うとともに,不正なメモリアクセスとなったアクセス先アドレスを表示するプログラムを作成しなさい. アドレスの情報はシグナルが渡すデータ構造から取得し,表示はシグナルハンドラの中で行いなさい.

ヒント: sigaction のマニュアルの siginfo_t に関する部分を参照.

練習問題(504)

sleep は実はライブラリ関数である. シグナルの機能を用いて,sleep 相当の機能を持つ関数 mysleep を作りなさい.

mysleep は sleep と同じ戻り値を返すようにし,さらに,それを確かめる実行例を含めるようにすること. 現在時刻は time 関数により取得できる. 使用が終わり不要になったシグナルの設定はキャンセルし,もとの設定に戻すこと. nanosleep システムコールは使用しないこと. mysleep はリエントラント(再入可能)である必要はない.

ヒント: 現在時刻は time 関数や gettimeofday 関数によって取得できる. Linux では clock_gettime 関数の利用が推奨されている.

練習問題(505)

キーボードから1文字入力を読み込む関数 getchar にタイムアウト機能を追加した関数 mygetchar を作りなさい.

実行例では,上記の仕様を満たしていることを,以下の2つを表示することにより示しなさい. mygetchar の戻り値として,場合に応じて,キー入力値,-1,-2 の3種類が返されることを実行例で示しなさい. -3 を返す機能を完全に実装することは面倒なので,その機能は実装しなくて良いし,実行例に含める必要もない. もちろん,実装しても良い.

mygetchar はリエントラント(再入可能)である必要はない.

ヒント: シグナルの設定に用いるフラグに注意しよう.
ヒント: Ctrl-D によって EOF を入力することができる.Ctrl-C によって,フォアグラウンドのプロセスに SIGINT シグナルを送信することができる.

練習問題(506)

練習問題(407)と同じように,親プロセスと子プロセスが交互に実行することにより,交互に1文字出力するプログラムを,シグナルを用いて書きなさい. fork で作る子プロセスは1つだけとする.