du

女房からテプラを買ってくるように下命された。何でまた急にテプラかと思って聞いて みると、年末大掃除に先だって荷物を整理して、綺麗にテプラを貼り付けておきたいとの事。

どこの雑誌の受け売りだい? そんなの3日で飽きるだろうに。でも、逆らうといろいろ な仕事が降ってきそうなので素直に従う事に。ホームセンターに行ったら、ピンキリで 種類があったよ。単独で動くのやパソコンから制御出来るものまで。そのうちで、一番 安いのを買ってきた。2980円也。単3電池6本で動くやつだ。

こんな値段のやつでも、仮名漢字変換が付いているのにはびっくり。やれ漢字が出ない だの、文字が小さいだのとぶつぶつ言いつつ、一生懸命にタグを作ってましたよ。こういう 事が楽しいんですかね? おいらだったら、紙に印刷して、それをセロテープで貼り付け て終わりにしちゃうけどね。

こうやって、めったに使わないガラクタが溜まって行くんだな。体脂肪も測れるという 体重計。使ったのは、せいぜい1週間で、今はもう埃を被っていますよ。後は、その場で 足踏みダイエット。雨の日も安心とか、テレビを見ながらダイエット出来るとかの ふれ込みだったな。

こういう、ガラクタをgcして、是非部屋を広くしておくれ。それが、大掃除ってもんだろう。 おいらの大掃除は、読まなくなった雑誌、書籍ですかね? 今日あたりからマークして おいて、年末にスィープしよう。

来年からは、世代別gcに挑戦だな。読んだ本を常に本棚の一番右に戻すと言う操作を 1年間繰り返す。来年の暮れには、目を瞑って本棚の左側から30冊、有無を言わさず に捨てる。この役は、情け容赦ない女房にやってもらえばいいのか。

あれ、このgcは、世代別じゃ無かったっけ? LRU法によるgcか。島根のあの人が詳しい な。RHG並みの高騰を狙って、gcの本が出たら買ってみよう。それがrubyへの応援ってもんです。

du

前回に引き続いて、今回はduです。まずはお約束の仕様書参照です。man du

リンクファイルの扱いをどうするとか事細かに説明がありました。Windowsのduもどきでは こういう説明って何処かにあるんでしょうか? いるかや冴子先生は、EXCELしか知らない オンチですからねぇ。ソース嫁なんてのは超絶望的ですから。細かい事は気にするなか。 気にする人は、VBかなにかで自前のduを書きましょう。

BSDのmanは仕様書にもなるし、ソースを読み解く時にヒントにもなるんです。今回のduに したって、参考資料として、fts ってライブラリーが上がっていました。

このftsって何? fts - ファイルの階層を横断する だそうです。どうやらこのライブラリー が肝になりそうなので、熟読してみました。その結果、duはftsの良き実例になっているに 違いないと確信しました。

du.c

今回は、ソース1本だけでした。自分の所へ持ってきて、gdbから使えるようにコンパイル しました。まずは、ちゃんと動いているか確認します。

[sakae@fb8 ~/work]$ ./a.out -h *
2.0K    Makefile
 20K    a.out
 14K    du.c
 18K    du.o

そんじゃ、得意のtrace をしていきます。

(gdb) run -h *
Starting program: /usr/home/sakae/work/a.out -h *

argがある時も、run commandに指定出来る(ようになったんだ)。emacs から gdb を 使っているので、ソースを見ながらが嬉しい。気分はIDEだな。重い思いして、日蝕とか 網豆なんて 入れる事ないじゃん。で、核心部分は、このあたりっぽい。

          if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL)
                  err(1, "fts_open");

  =>      while ((p = fts_read(fts)) != NULL) {
                  switch (p->fts_info) {
                  case FTS_D:                     /* Ignore. */

このwhileを気の済むまでぐるぐる回るんだな。今回は、switch文のdefaultsの部分へと 分岐してゆく。そして、その中で

                                  if (hflag) {
  =>                                      prthumanval(curblocks);
                                          (void)printf("\t%s\n", p->fts_path);

printfを実行すると、

(gdb) n
2.0K    Makefile

こんな風に、表示されたよ。と言うことは、prthumanvalでサイズを表示してるんだなと 想像が付く。そう思って、prthumanvalを追って行くと、人間様用の表示をするかいとかの 判定してて、printfで印字してた。

なお、-c オプションを付けると、トータルを表示してくれて、Windowsの超遅いモードと 同様になる。何処でやってるかと思ったら

                          p->fts_parent->fts_bignum += curblocks;
                  }
  =>              savednumber = p->fts_parent->fts_bignum;

p->fts_parent->fts_bignum に足しこんでいる。Windowsでは、この部分に無駄な callbackが 挿入されてて、紙芝居を実現してるんだな。勿論、質実剛健にunixには、そんなコードは 微塵も無い。これが、windowsもどきを実現してる、GとかKとかのファイルマネージャーだと 軟弱になってるんだな。GとかKは、入れた事はあるけど、真面目に使った試しがないので、知らない 。

以上、解析終わり。

fts

ついでだから、ftsについてもちょっと。。

まず上のdu.cのコードで、switch分岐があった。あっさりとdefaults節が実行されちゃった けど、他にどんなのがあるか、ちと列挙。

                  case FTS_D:                     /* Ignore. */
                          if (ignorep(p))
                                  fts_set(fts, p, FTS_SKIP);
                          break;
                  case FTS_DP:          /* dirの場合の、帰り順処理 */
                           :
                  case FTS_DC:                    /* Ignore. */
                          break;
                  case FTS_DNR:                   /* Warn, continue. */
                  case FTS_ERR:
                  case FTS_NS:
                          warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
                          rval = 1;
                          break;
                  default:

どんどんdirに潜って行って、帰り順で表示を司っているようだ。後 du.c の中で、fts_bignum なんていう思わせぶりなやつが出ていたけど、fts.h を見たら

        long long fts_number;           /* local numeric value */
#define fts_bignum      fts_number      /* XXX non-std, should go away */

誇大広告は、JAROの命により、いづれ除去されるっぽい。

で、fts.cは何処に? 探したら、/usr/src/lib/libc/gen に入っていた。ちょっと見する。

static const char *ufslike_filesystems[] = {
        "ufs",
        "nfs",
        "nfs4",
        "ext2fs",
        0
};

こんな定義が有ったよ。そんじゃ、ntfsとかzfsはどうなるのだろう? 大いなる疑問だ。 また、長い々fts_read関数の中には、pre-order と言う説明があるんだけど、その反対語の post-orderってのは無いな。pre - post って対だと思うんだけど。。。英語知らなすぎ?

別の手段で、FTS_DPで探してみたら、隅っこの方に、post-orderって書いてあった。emacsの 操作を誤ったかな。でも、ちゃんとコードを追おうと思うと、紙に出さないとだめだな。 今月のSDでは、ソースの読み方って特集があるようだけど、どんな方法を推奨してるのかな?

興味津々。でも、家には、Code Readingなんて本も有ったような。読み返してみるかな。