ぱたへね

はてなダイアリーはrustの色分けができないのでこっちに来た

lsを読まずにプログラマを名乗るな!

 なかなか挑発的なタイトルのlsを読まずにプログラマを名乗るな!を読みました。タイトルとは違って、lsの実装を丁寧に説明してあって勉強になりました。lsのソースコードを読みながら、システムコールアルゴリズム、多言語化等の幅広い話題に触れることができます。いくつかCのプログラムを書いていて、次の次のステップに進みたい人にお勧めです。

なぜlsか

 lsを題材にしている理由について、私なりにまとめ直しました。

  • デイレクトリの操作などでシステムコールの使い方がわかる
  • 再帰呼び出し、名前順にソート等の定番アルゴリズムが使われている。
  • 言語化対応
  • 普段よく使うプログラムなので挙動が想像しやすい
  • 限られたリソースで動かす為の技が所々にある。

 普通のプログラマならlsやdirは必ず使うことになるので、良い題材を選んだと感じました。

本の内容

 ls.cから、テーマに沿った部分を抜き出しての説明があります。
 例えばmain関数でディレクトリを抽出するところの処理では、このように説明されています。

  if (n_files <= 0)
    {
      if (immediate_dirs)
        gobble_file (".", directory, NOT_AN_INODE_NUMBER, true, "");
      else
        queue_directory (".", NULL, true);
    }
  else
    do
      gobble_file (argv[i++], unknown, NOT_AN_INODE_NUMBER, true, "");
    while (i < argc);

  if (cwd_n_used)
    {
      sort_files ();
      if (!immediate_dirs)
        extract_dirs_from_files (NULL, true);
      /* 'cwd_n_used' might be zero now.  */
    }

このソースに対して、cwd_n_used変数がどのような動きをするのか、immediate_dir変数によってどう動きが変わるのかの説明があります。

 前章で説明したように、コマンドラインの引数で指定されたファイル・ディレク
トリに対するgobble_file()呼び出し(1397行)を終えた時点で、cwd_n_used
が非ゼロになります。
 その上で、immediate_dirs変数にfalseが格納されていることから、
前章のケースでは実行されなかった、1404行のextract_dirs_from_files()
呼び出しが実行されます。

丁寧な説明と、いろんな角度からのコラムがあり、最後まで楽しく読めました。

知らなかったこと

 この本を読んで勉強になったことをまとめてみます。

条件成立時の値

 関係演算子、等値演算子は、0と非0を返すと思っていたのですが、0か1を返すと規格で決まっています。

  for (i = 0, j = 0; i < cwd_n_used; i++)
    {
      struct fileinfo *f = sorted_file[i];
      sorted_file[j] = f;
      j += (f->filetype != arg_directory);
    }
  cwd_n_used = j;

それを使うと、このような条件が成立したときのみインクリメントというコードが書けます。

整列処理

 ソートです。lsのソートは、libcのqsortを使わず、GNU coreutilsのmpsortを使っています。mpsortは、ソートする対象の5割増しの領域を確保しないと行けません。5割増しというのが面白いですね。mpsortを使ったソートの手順も、わかりやすく説明されています。

1.空き領域を使って、対象の後半部分を整列。結果は後半部分に上書き。
2.対象の前半部分を整列。結果は空き領域に上書き。
3.整列済みの前半部分(空き領域に格納)と後半部分とで、マージソートを実施。結果は整列対象格納領域に上書き。

こんなやり方があるんだと関心しました。

シグナル処理

 最初はlsで使うシグナル処理って何だろうと疑問に思っていたのですが、読んでいて納得しました。最近のlsは色を変えて結果を表示します。その時に端末に制御コードを送って色をつけるのですが、Ctrl-C等でlsが強制終了された時に端末の状態をもどす必要があります。これも言われるまで気がつきませんでした。

まとめ

 全体的に面白そうなトピックを選んで丁寧に説明してあり、最後まで一気に読んでしまいました。歴史のあるソースなので、プアな環境で動かすための工夫と、高速化の為の工夫が同居していて、筆者が首をかしげているような所もあり面白かったです。もう一歩踏み込んで欲しい所もあるのですが、そこは自分で勉強しましょうということだと思います。
 残念な所が2つあります。表紙とタイトルです。本の中身は、すごく真面目に丁寧にソースコードと向き合っているのに、表紙とタイトルが挑発的で損をしていると感じました。