システムコールはユーザプログラムからシステムが持っている機能を呼び出 すための方法です。システムコールはカーネルモードと呼ばれる特権モードで 実行されますが、プログラマから見た場合は実際にはCの関数として呼び出さ れます。一般的なCの教科書では(D OS上のCなども扱うため)C言語のライブラ リ関数I実行時関数と呼ぶ場合もあります)と区別せずに解説される場合も多い ようです。実際にはライブラリ関数からもシステムコールが呼び出されるもの があります。システムコールでは一般的にはユーザモードで引数のテーブルを 用意してソフトウエア割り込みによってカーネルモードに移行し実行した後、 再度ユーザモードに戻って値を返します。これによってカーネルに変な値が渡 されてシステムクラッシュするのを防いでいます。
どのようなシステムコールが用意されているかは、man 2 introで見ること ができます。また各々のシステムコールの使い方はmanで見ることができます。 manページのセクション2はシステムコールに関するものです。ちなみにCライ ブラリ関数はセクション3に記述されています。これも同様にmanで見ることが できます。ですから本書では引数の説明は必要最小限にとどめます。実際にプ ログラムを書く場合はmanで確かめながら書いてください。U NIXでシステムコー ルを含むCのプログラムを書くときは別のウインドウにmanページを表示させな がら書いていくのが効率的です。それぞれのシステムコールのmanページには インクルードする必要のあるヘッダーファイルの名前も示されます。 /usr/includeにある*.hファイルも見ておきましょう。関数の名前・引数・戻 り値は*.hファイルで定義されます。特にUNIXのカーネルの構築にも使われる 定義やシステムコールの定義は/usr/include/sysにある*.hファイルで宣言さ れています。
基本的にシステムコールの戻り値は失敗した場合-1で、成功した場合はそれ 以外の、コール毎に決められた値が返されます。失敗した場合errnoという大 域変数にエラーコードが設定されています。それを調べることにより失敗の原 因を知ることが出来ます。エラーコードが何を表しているかは /usr/include/sys/errno.hに定義されています。perrorコールでメッセージを 標準エラー出力に書き出すことも出来ます。
#include <errno.h> ... st = system_call( ); /*任意のシステムコール*/ if( st == -1 ) /* Error */ { perror( 0 ); /* 最新エラーを出力*/ if( errno == ENOENT ) {... /* エラーがENOENTの場合*/
本書の例題では読みやすさのため戻り値の検査を省略してあるところがありま すが、通常のプログラミングでは検査をするように習慣づけておいてください。
実行可能プログラムにリンクされるべき関数ライブラリーについてもCの実 行時ライブラリーである/lib/libc.aもしくは/usr/lib/libc.aに含まれていま す。ですからccコマンドでリンクまで行うときにシステムコールの関数を含ん だライブラリーをひっつけることを意識する必要はありません。
システムコールはシステムの様々な資源(リソース)にアクセスするための方 法を提供します。CPUの割り振り、メモリーの割付、プロセス管理、入出力、 ファイルシステム、ネットワーク、時間管理、例外処理などです。そのような システムコールのうち、プロセス間通信に使われるものは次の節で別に説明し ます。ここではそれ以外のもので、オンラインプログラムで使われるものを説 明します。