C/400

81. pipe と標準入出力について(6)

既に説明したように子プロセス上で CGI を実行するには

同一プロセス上での標準入出力

という pipe を実現する必要があった。
System i の開発者は CALL 命令によって同一プロセス上に新たな実行スタックを
積み重ねて実行させることが日常になっているが Windows や UNIX では
プログラムの呼び出し&実行は別のプロセスとなることが一般的であるので
このような同一プロセス内での pipe を使うことはあまり例がない。
もちろんインターネットにサンプルを探しても見つかることはない。
この pipe の実現に困難を極めたのが system i の次の特異性であった。

  • 標準入出力には始めからファイル識別子が割り振られていない。
    Windows や UNIX では標準入力は 0, 標準出力は 1 と初期値で
    割り振られているが System i の標準入出力にはファイル識別子が
    ないのだ。
    pipe とは二つのファイル識別子を結びつけるものであったことを
    思い出して欲しい。

  • 環境変数 QIBM_USE_DESCRIPTOR_STDIO を Y にセットすると
    QtmhRdStin は 0, QtmhWrStout は 1 のファイル識別子が与えられる。
    ただし QIBM_USE_DESCRIPTOR_STDIO=Y であるときは他の
    標準入出力( fwrite 等)の入出力は無視されてしまう。
    従って使用後は QIBM_USE_DESCRIPTOR_STDIO=N に戻しておく必要がある。

    • ⇒ このことがわからなかった。もちろん IBM マニュアルにも記述は
      無かったのだが米国の Scott Klement が偶然にも Q&A で読者の質問に
      答えている記事を見つけて実験したらまさにそのとおりであった。
      ( QIBM_USE_DESCRIPTOR_STDIO を教えてくれたのが
      Scott Klement でありその後の実験は当社が行った。)
      一体、Scott Klement はどうやってこのことを知ったのだろうか ?
      これが本題の解決のための糸口になったのは言うまでもない。

  • 標準入出力をリダイレクトできるのは標準入力の識別子が 0 で
    標準出力の識別子が 1 の場合だけである。

    ⇒ この問題があるために 0 である socket 識別子と標準入力 0 が
    バッティングしてしまったのだが何とか dup 関数によって
    Backup & Recovery して切り抜けることができた。

ポイントは環境変数 QIBM_USE_DESCRIPTOR_STDIO=Y であったが偶然にも知ることが
できたのはラッキーであった。
これによって CGI の標準出力をリダイレクトしてブラウザへ送信することが
可能になったのである。
QIBM_USE_DESCRIPTOR_STDIO に関しては IBM マニュアルにも少しの説明があるが
これが API : QtmhRdStinQtmhWrStout の動作に関連しているとはどこにも
書かれていない。まさにインターネットの山から見つけ出した貴重な情報である。
Scott Klement 氏には深く感謝する次第である。