この /tmp/config-err-XXXXXX はなんだろう

Ubuntu を使っていて、ふと /tmp ディレクトリに _config-err-fdecaa_ というファイルが出来ているのに気付いた。

所有者は非 root のログインユーザーで、中身はカラ。

これはなんだろう。

環境
----

- Ubuntu 15.04
- LightDM 1.14.4

調査
----

### ウェブ検索

ファイル名の後ろのランダムっぽい部分を削り _"/tmp/config-err"_ で検索すると、早速それっぽい話題が見つかった。

[Comment #40 : Bug #678421 : Bugs : gdm package : Ubuntu](https://bugs.launchpad.net/ubuntu/+source/gdm/+bug/678421/comments/40)

バグの詳細はわからないが、どうやら [LightDM](https://freedesktop.org/wiki/Software/LightDM/) 関連の動作で吐き出すものらしい。

LightDM なら今使っているデスクトップ環境だ。

### 端末内検索

```bash
$ sudo grep -rI "config-err-" /usr 2>/dev/null
/usr/sbin/lightdm-session:ERR=$(mktemp --tmpdir config-err-XXXXXX)
/usr/lib/lightdm/config-error-dialog.sh:        TEXT_FILE=$(mktemp --tmpdir config-err-kdialog-XXXXXX)
```

謎のファイルがある端末の中を `grep` で検索したら、まさに LightDM のファイルが引っかかった。

あれは `mktemp` コマンドで作られたファイルらしい。

### /usr/sbin/lightdm-session を読む

例のファイル名と同じ形式 _config-err-XXXXXX_ を含む方のファイルを読んでみる。

X セッション用のラッパー・スクリプトらしい。

今回の疑問と関係がありそうな部分を抜粋。

```bash:/usr/sbin/lightdm-session
# temporary storage of error messages
ERR=$(mktemp --tmpdir config-err-XXXXXX)

source_with_error_check () {
    CONFIG_FILE="$1"
    echo "Loading $CONFIG_FILE"
    . "$CONFIG_FILE" 2>"$ERR"
    if [ -s "$ERR" ]; then
        . /usr/lib/lightdm/config-error-dialog.sh
    fi
    cat "$ERR" >>/dev/stderr
    truncate -s 0 "$ERR"
}

# Load profile
for file in "/etc/profile" "$HOME/.profile" "/etc/xprofile" "$HOME/.xprofile"; d
o
    if [ -f "$file" ]; then
        source_with_error_check "$file"
    fi
done
```

どうやら profile 系のファイルを読み込むときに作られるものらしい。

一時ファイルに直接関わる部分では、

```bash
ERR=$(mktemp --tmpdir config-err-XXXXXX)
```

一時ファイルを作ってパスを `$ERR` に格納して、

```bash
if [ -s "$ERR" ]; then  
    . /usr/lib/lightdm/config-error-dialog.sh  
fi
cat "$ERR" >>/dev/stderr
```

エラーがあればダイアログや標準エラーに出力して、

```bash
truncate -s 0 "$ERR"
```

最終的にサイズを 0 に切り詰める。

自分が見たのはこの抜け殻状態の一時ファイルだ。

しかし、なぜ？

消さずに残すんだろうか？

### /usr/lib/lightdm/config-error-dialog.sh を読む

`grep` で引っかかったもう一方を読んでみる。

上記のスクリプト _lightdm-session_ でも、ダイアログを呼び出す場面で `.` コマンド経由で読み込まれている。

```bash:/usr/lib/lightdm/config-error-dialog.sh
TEXT="$PARA1\n\n$(fold -s $ERR)\n\n$PARA2"

if [ -x /usr/bin/kdialog ]; then
        TEXT_FILE=$(mktemp --tmpdir config-err-kdialog-XXXXXX)
        echo -n "$TEXT" > "$TEXT_FILE"
        kdialog --textbox "$TEXT_FILE" 500 300
        rm -f "$TEXT_FILE"
elif [ -x /usr/bin/zenity ]; then
        zenity --warning --no-wrap --text="$TEXT"
fi
```

一時ファイルに関わる部分を抜き出していくと、

```bash
TEXT="$PARA1\n\n$(fold -s $ERR)\n\n$PARA2"
```

エラー文の生成。

`$ERR` は _lightdm-session_ で定義した一時ファイルのパス。 `$PARA*` は「コンフィグファイルにエラーがありますよ」って文言。

```bash
if [ -x /usr/bin/kdialog ]; then
        TEXT_FILE=$(mktemp --tmpdir config-err-kdialog-XXXXXX)
        echo -n "$TEXT" > "$TEXT_FILE"
        kdialog --textbox "$TEXT_FILE" 500 300
        rm -f "$TEXT_FILE"
```

`kdialog` コマンドが利用可能なら、エラー文をもとに新たな一時ファイルを作ってダイアログで開く。一時ファイルは `kdialog` で読み込むためのもので、使い終わったら消す。

こちらでは一時ファイルを消している。

え、消すんだ。

### 再確認

そもそもこの _config-err-XXXXXX_ は LightDM が生成したものなのだろうか。

端末を再起動して仮想コンソールからログインすると /tmp には何も入っていなかった。

デスクトップ GUI からログインすると /tmp に _config-err-XXXXXX_ 形式のファイルが生成された。中身はなし。ログアウトし直すと別の名前の _config-err-XXXXXX_ が増えた。

```bash
# truncate -s 0 "$ERR"
rm "$ERR"
```

サイズを 0 にする部分を削除に書き換えて、さらに再起動しても無事に動いた。

どうやら LightDM の一時ファイルで間違いないらしい。

結論
----

_config-err-fdecaa_ は LightDM 用の一時ファイルだ。

しかし、新たに生まれた謎。一時ファイルを使った後に抜け殻の状態で残している理由はわからない。

モヤモヤする。

一時ファイルのパスをもつ変数 `$ERR` は _config-error-dialog.sh_ 以外で使われていないようだ。

タイミングをずらして実行する可能性があるから、ファイルを残すことで読み出し側でエラーを起こさせない、またはいちいち対策させないためだろうか？

たぶん、謎というほどのことではない。

しかし、モヤモヤする。