ヒアドキュメントの実装
そろそろ yash にもヒアドキュメントを実装したい。
bash やら zsh やらの挙動を見てみると、他のシェルは全てヒアドキュメントの内容を全て一時ファイルに書き出してからリダイレクトしているようだ。一時ファイルを使うのは多分正攻法だが、わざわざ一時ファイルを作らなくてもパイプで十分じゃないかという気もする。
一時ファイルを使う場合は、どうやって一時ファイルを作るかという問題がある。POSIX でいうところの XSI 拡張が使える環境では mkstemp 関数が使えるが、それ以外の環境では余り役にたちそうな関数がない。tmpnam 関数は使用回数に制限があるし、tmpfile 関数はエラー時に勝手にエラーメッセージを出される虞がある。tempnam 関数は中で tmpnam 関数を使っている可能性があるので駄目。となると mkstemp 関数を自作するしかなさそうだが、そんなことするくらいならパイプを使った方が手っ取り早そうだ。
パイプを使う場合は、パイプの容量に気を付けないといけない。limits.h ヘッダに PIPE_BUF という定数が定義されていて、少なくとも PIPE_BUF バイトはパイプの中にデータを溜めておけることが保証されている。ヒアドキュメントの長さがこれ以内なら、ヒアドキュメントの内容全部を一度にパイプに書き込めるので話はややこしくない。ヒアドキュメントがこれより長いと、一度には書き込みきれないので残りを後で書き足す必要がある。どうやって後から書き足すかだが、まあ書き足し専用の子プロセスを fork するくらいしかないだろう。しかしこの方法では書き足しが完了した時点で親プロセスすなわちリダイレクトの対象となるプログラムに SIGCHLD が行くことになるし、親プロセスが wait しないとゾンビプロセスが残ってしまう。さすがにこの方法は避けるべきか。
| 固定リンク
コメント