こんばんは、川合です。 OSASKのコンソールAPIの概略について書きます。 結局のところ、コンソールAPIはファイル周りのファンクションの追 加ということに尽きます。フィルターなどは標準入力から取り込んで、 標準出力へ出すだけです。後はコマンドラインオプションを取り込める ことくらいです。標準入力や標準出力は普通のファイルだったりするこ ともありますが、コンソールや他のタスクとパイプでつながっているこ との方が多いでしょう。ということで、ここからはそのパイプについて です。 OSASKのAPIにもパイプのサポートがあります(今はありませんが、こ れからつけます)。しかしパイプは特別な仕組みではなく、ただのモジ ュール(ファイル)です。今までと同じように、普通にメモリマップト ファイルでアクセスします。 パイプへのリードアクセスを考えてみましょう。今までのファイルア クセスの方法だけではどこまで出力されているのか、それは分かりませ ん。パイプなんですから、徐々に出力が付け足されていくわけです。・ ・・したがって今までのファイルアクセス方法でオープンした場合、パ イプの出力側のタスクが全て出力しおわるまで、オープンは完了しませ ん。これはちょうどMS-DOSの一時ファイル方式と同じになります。 これでは不便ですので、これから新しいモジュールアクセスファンク ションが追加されます。これらを使うなら、出力側が全て出しおわらな くても、パイプをリードできます。 追加されるファンクションは以下の通りです。 (1)アクセスロック要求 (リード一時・リード確定・リードライト) (2)ロック開放 (3)アクセス可能範囲通知 (リード・ライト、一時・確定) (4)通知シグナル設定 (5)通知シグナル送信 (リード・ライト・サイズ変更、一時・確定) UNIXなどではファイルにロックをかけることができますが、OSASKで はモジュール全体にロックをかけるばかりではなく、部分的にロックを かけることができます。 また書きおわった領域に対しても、もうその領域は書き換えるつもり がないのか、それともまたその領域を書き換えるかもしれないのか、そ の意志を示す必要があります。 一方、リード側も読み終わった領域に対して、またその範囲を読み込 むつもりがあるのか、それとももう読むつもりがないのか、意志を示す 必要があります。システム側としては、今後誰からも相手にされないと 確定した領域については、どんどん捨てます。 (例 - 1) さて、では、"hello, world"と標準出力に出力するためのプログラム を考えましょう。 面倒なことを極力減らすという観点に立てば、スロット0x200は標準 出力に割り当てられているので(どのスロットを何に割り当てるかはリ ンク時に決めます)、そこへ該当文字列を出力することだけを考えます 。 スロット0x200を13バイトにリサイズして、適当にマップし、"hello, world\n"を書き込みます。そしてタスクを終了すれば終わりです。こ れが一番簡単な方法です。問題ありません。なお、スロット0x200は起 動時にオープンされているので、プログラム内でオープン処理をする 必要は全くありません。 (例 - 2) 今度は同じ"hello, world"をもうちょっとややこしい手順で出力して みます。 まずスロット0x200に対して追加リサイズ権とオフセット0〜12に対し てのリードライト権を要求します(上記の(1))。この時ロック解除要 求に応答するかどうかを設定できるのですが、ここでは解除要求に応じ ないとします。権利を獲得できるとシグナルが来ることになっているの で、それを待ちます。シグナルがきたらリサイズしてマップして書き込 んでタスク終了です。ロックを開放する必要はありません。 (例 - 1)ではこのようなロック要求をしませんでしたが、それは起動 時に簡易オープンするようにリンクで指定しておいたからです。(例 - 2)では拡張オープンなので、自分でロックを制御します。なお、タスク が終了するとファイルはクローズされますし、ロックは全て解除されま す。 (例 - 3) 標準入力から取り込んだ内容にたいしてtoupper()して出力するフィ ルターを例に取ります。まずは、入力も出力も簡易オープン版から。 スロット0x200が入力で0x210が出力になっているとしましょう。簡単 です。0x200のサイズを取得して0x210をリサイズし、どちらもマップし て、あとはひたすらtoupperしながらコピーするまでです。終わったら 終了です。 この例ですと、このフィルターをコンソールで実行した場合、コンソ ールでの入力が終わらないと出力が始まりません。 abcdefg hijklmn ^z ABCDEFG HIJKLMN のようになります。これはコンソールでの入力が終わらないと入力側の パイプのオープンが完了せず、タスクが起動できないからです。こうい う欠点が簡易オープンにはあります。 (例 - 4) 今度は(例 - 3)の拡張オープン版です。 まずスロット0x200に対して通知シグナルを設定します。リード確定 領域変更についてです。そしてとりあえずスリープです。 シグナルがきたら、それは間違いなくリード確定領域変更シグナルな ので、仕事を始めます。まず確定した領域をシグナルから読み取り、0x 200と0x210の両方にその範囲でロックをかけます(リード確定ロックと リードライトロックと追加リサイズロック)。そして、0x210側のサイ ズが足りなければ変更し、マップしてtoupperしながらコピーします。 終わったら、ロックを解除し、0x200と0x210の終了した範囲にはリード ライト確定完了のシグナルを通知し、そしてまたリード確定領域変更シ グナルを待ちます。 これで、 abcdefg ABCDEFG hijklmn HIJKLMN ^z というふうになります。 (例 - 5) さらに(例 - 4)を改造して、リード一時確定領域変更シグナルにも対 処すれば、もっと面白いことになります。一時確定というのは、出力側 が「とりあえず出力するけど、この部分はあとで変えるかもしれない」 という意味です。この場合、このフィルターは一時確定ライト完了で応 じることになります。 この場合でも、もちろん普通のフィルターとして使う分には変わりま せん。しかし、入力をコンソールにして、出力先を一時確定対応teditc にするとすごいことになります(パイプも普通のファイルとして扱える のでテキストエディタで開けます。teditcをクローズするとパイプはな くなってしまいますが)。入力した文字がEnterを押す前からteditcの 方に大文字化して出力されるのが分かるでしょう。サイズもコンソール でのキー入力にあわせて小刻みに変化します。 なんなら入力側だってteditcでいいのです。パイプはファイルです。 何もコンソールに直接入力するだけが能ではありません。teditcなら前 の行に戻って編集することもできますし、切り貼りもできます。コンソ ール入力よりずっといいですね(笑)。 テキストエディタを2つ開いて、その間をフィルターで挟む、なんて ことができるOSが他にあるでしょうか?役に立つかどうかは別にして、 破格の面白さだと僕は思います。 結局、パイプとファイルが統合されているわけです。 --- 以上のやり取りは、とても面倒だと思われたかもしれません(僕は思 いました)。しかし心配することはありません、なんならライブラリを 使えばいい訳です。fgetcやfputcでやることもできるでしょう。一時確 定には対応できませんが、普通のフィルター程度の機能ならこれでOKで す。 なお、以上のややこしいやり取りはパイプのみならず普通のファイル にもできます。これにより、teditcで書き換えたら即座に同じファイル のbeditcに反映した、なんていうことも可能になります(どちらも拡張 オープン版に書き直さなきゃいけませんが)。また今のteditcとbeditc はどちらも簡易オープンなので、同時に同じファイルをオープンするこ とはできなくなります(オープンが完了しないか、もしくはエラーシグ ナルが返される)。 それでは。 -- 川合 秀実(KAWAI Hidemi) OSASK計画代表 / システム設計開発担当 E-mail:kawai !Atmark! imasy.org Homepage http://www.imasy.org/~kawai/