てきとうなメモ

本の感想とか技術メモとか

git commitでviが起動されてコミットログを書き込むとエラー

$ git commit -a
error: There was a problem with the editor '/usr/bin/vi'.
Please supply the message using either -m or -F option.

というようなエラーになる。

エディタとして/usr/bin/viを使ってコマンドの戻り値が0以外だったので、上記のエラーになったらしい。

$ /usr/bin/vi
$ echo $?
1

と、単体で実行してもエラーになっていた。/usr/bin/vimだとエラーにはならない

$ /usr/bin/vim
$ echo $?
0

ので、/usr/bin/vimをエディタにしたらエラーはでなくなった。

git config --global core.editor /usr/bin/vim

しかし、/usr/bin/viは/usr/bin/vimへのシンボリックリンクなんだが。

で、ソースをみるとargv[0]をみてviとか/usr/bin/viで起動されていると動作を変えているっぽい。

    {
	char *base = strrchr(argv[0], '/');
	if (base) base++; /* skip over slash */
	else base = argv[0];
	Unix2003_compat = 0;
	if (strcmp(base,"vi")==0) {
	    Unix2003_compat = COMPAT_MODE("bin/vi", "Unix2003");
	} else if (strcmp(base,"ex")==0) {
	    Unix2003_compat = COMPAT_MODE("bin/ex", "Unix2003");
	}
    }

COMPAT_MODEマクロはcompat_mode関数を呼んでいる。compat_modeはfunctionとmodeを引数にとる。

基本的にfunctionはチェックされていなくて、modeに"Unix2003"が渡された場合は、環境変数COMPAT_MODEが設定されていてlegacyだったらfalseを返し、unix2003だったらtrueを返し、設定されていなかったら、trueを返すというようなもの。

vimのコードのUnix2003_compatが有効になって以下のif文が有効になったため、エラーになっているっぽい。

/* Exit properly */
    void
getout(exitval)
    int		exitval;
{
    ...

    /* When running in Ex mode an error causes us to exit with a non-zero exit
     * code.  POSIX requires this, although it's not 100% clear from the
     * standard. */
    if (exmode_active || Unix2003_compat )
	exitval += ex_exitval;