この文書は mod_mmap_static モジュールを Apache 2.0 用に移植した時に 学んだ経験をもとに書いた、最初の手引き書です。まだまだ完全じゃないし、 ひょっとすると間違っている部分もあるかもしれませんが、 取っ掛りにはなるでしょう。
クリーンナップルーチンは apr_status_t 型である必要があります。 そして、apr_status_t 型の値を返さなくてはなりません。 クリーンナップ中のエラーを通知する必要がなければ、返り値は普通、 ARP_SUCCESS です。たとえエラーを通知したとしても、 すべてのコードがその通知をチェックしたり、 エラーに応じた動作をするわけではないことに気をつけてください。
初期化ルーチンは処理全体から見てしっくりくるような意味を表すように、 名前が変更されました。ですから、mmap_init から mmap_post_config のようにちょっと変更されました。 渡される引数は大幅に変更され、次のようになりました。
データ型のほとんどは APR に移されました。つまり、 いくつかの名前が前述のように変更されています。 施すべき変更点の簡単な一覧を以下に示します。
新しいアーキテクチャでは作成した関数を呼び出すのに 一連のフックを使用します。このフックは、新しい関数 static void register_hooks(void) を使って登録するよう、 モジュールに書き足さなくてはなりません。 この関数は、なにをすべきか一旦理解してしまえば、 十分にわかりやすいものです。 リクエストの処理のあるステージで呼び出さなくてはならない 関数は登録する必要があります。ハンドラは登録する必要はありません。 関数を登録できるフェーズはたくさんあります。 それぞれのフェーズで、関数を呼び出す相対的な順番は、 かなりの程度制御できます。
以下は、mod_mmap_static に追加したコードです:
static void register_hooks(void) { static const char * const aszPre[]={ "http_core.c",NULL }; ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE); ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST); };
ここでは呼びだすべき二つの関数を登録しています。一つは post_config ステージ用 (ほとんどすべてのモジュールはこれが必要です) で、 もう一つは translate_name フェーズ用です。 それぞれの関数は名前は違うけれども形式は同じであることに注意してください。 それでは、形式はどのようになっているでしょうか?
ap_hook_[フェーズ名](関数名, 先行, 後行, 位置);
3つの位置が定義されています…
位置を定義するには、上記の「位置」を指定し、 修飾子である「先行」と「後行」で手を加えます。 「先行」「後行」は、呼ばれるべき関数のリストです。 「先行」は関数の実行前に呼ばれるもので、 「後行」は実行後に呼ばれるものです。
mod_mmap_static の場合、post_config ステージでは必要ありませんが、 mmap_static_xlat が core モジュールが名前の変換を実行した後に 呼ばれなければなりません。 そこで aszPre を使って HOOK_LAST の修飾子を定義しています。
モジュールの定義を作成する際に注意しなければならない ステージの数は激減しています。古い定義は次のようになっていました。
module MODULE_VAR_EXPORT [モジュール名]_module = { STANDARD_MODULE_STUFF, /* 初期化関数 */ /* ディレクトリ設定作成関数 */ /* ディレクトリ設定マージ関数 ― デフォルトは「上書き」 */ /* サーバ設定作成関数 */ /* サーバ設定マージ関数 */ /* コマンド・ハンドラ */ /* ハンドラ */ /* ファイル名変換 */ /* check_user_id */ /* 認証チェック */ /* アクセス制限チェック */ /* MIME 型チェック */ /* 調整 */ /* ログ出力 */ /* ヘッダパーサ */ /* 子プロセス初期化 */ /* 子プロセス終了 */ /* read-request 後 */ };
新しい構造体はとってもシンプルです…
module MODULE_VAR_EXPORT [モジュール名]_module = { STANDARD20_MODULE_STUFF, /* ディレクトリ毎設定構造体作成 */ /* ディレクトリ毎設定構造体マージ */ /* サーバ毎設定構造体作成 */ /* サーバ毎設定構造体作成マージ */ /* コマンド・ハンドラ */ /* ハンドラ */ /* フック登録 */ };
このうちのいくつかは古いものから新しいものに直接読み替えられるもので、 いくつかはそうではありません。どうすればいいのかを要約してみます。
直接読み替えられるステージ:
古い関数の残りのものはフックとして登録されるべきです。 現時点で次のようなフック・ステージが定義されています…