vi process.cc; make

またしてもprocesss.ccを。
forkした子プロセスの標準出力と標準エラー出力を親プロセスでぶんどって、ごにょごにょやろうという処理。


pipeをぶんどった後、そこからread()し続けてstringstreamにどんどん入れていくスレッドを立ち上げる。stringstreamになにか入れたら、pthread_cond_broadcast()することにする。子プロセスが終了したら、stringstreamにeofbitフラグを立てる。
一方親分クラスは、pthread_cond_timedwait()でstringstreamを見張る。stringstreamに何か入ったら中身を返すメソッドを作る。
main()では、stringstreamのeofbitフラグを検出するまで中身をゲットして、いろいろいじってから表示する。あるいはゲットした文字列を解析して使う。
マルチプロセスでマルチスレッド。なんか泥沼にハマっている気がする…。
実際にmain()あたりから使うインターフェースは結構すっきりできたけど、C++的じゃないところ(read()とかpthread_createとかとか)とその周辺は、どうしてもごちゃごちゃしてしまう。



…要するに、シェルスクリプトとだと

#!/bin/sh
for dev in $(ifconfig -a 2>/dev/null | grep "HWaddr" | sed "s/[[:space:]].*//");do
    ごちゃごちゃ
done

とやるところの処理を、C++でやりたいだけで。
シェルスクリプトって凄いですね…。かたや1行、かたや500行ですよ。あ、正規表現もある…これ作ってない。ま、boost::functionとかboost::bindとかとかを多用している今更、boost::regexを使ってしまえば良かろう…。
と言いながら、boost::threadは使っていない。libboost_theradを要求するのがイヤで…。pthreadでも書けるし…。boostの方が移植性が高い!と言っても、そもそもVIVERに移植性が無い。突然「/procをマウントせよ!」この時点でもWindowsでもMacでも動かない。SolarisとかFreeBSDあたりには移植できると面白そうだけどな…ブートプロセスが全然違うからな…。SquashFSも無いしDevice Mapperも無い、というか、機構が違う。



最初にVIVERをシェルスクリプトで作ったのは、結構正解だったのかもしれない。
でも、例外処理は明らかにきめ細かく向上中。デバッグメッセージもしっかり。で、コメントもしっかり入れて。トリッキーなコードも無い。(viver 0.2は、シェルスクリプトのトリッキーなコードばかりで成り立っている…
シェルスクリプトの「変数が全部グローバル」から比べると、とことんカプセル化できるので安心感がまるで違う。



…むむ。今ひらめくに、ifconifgのソースを解析して、ifconfig自体を中に組み込んでしまえば良いのか?そうすれば正規表現も要らないな…。というか、システムコールでネットワークインターフェースってわかるのかな?/procとか/sysを調べるとわかるとか?やや、そうかもしれない。いやむしろそうに違いない…。



まぁ、何かの役には立つか。(バグ発生の役に立つか…


わざわざスレッドを立ち上げる必要性が良くワカランな…。
とりあえずまたMercurialソースコード管理を始めたので、消してもあとで掘り出せるから良い良い。