- UNIXプログラミング質問すれ Part10
657 :デフォルトの名無しさん[]:2014/05/31(土) 07:45:18.26 ID:6bjDZoIF - OpenBSDのdiffソースをもってきた理由は、ライセンスの問題からです。
ところで、エラーの原因が判明しました。 set_argstr()の中で、argsize が負の値になり、xmalloc(argsize) が内部で呼び出しているmalloc(argsize)に失敗し、err(2,NULL) を呼び、 err()が、malloc()が設定したグローバル変数 errno に応じたメッセージ として「Cannot allocate memory」を出していたのでした。 なお、set_argstr(av,ave)のavには、main() に渡された状態の argv がそのまま 渡され、ave には、-オプションを除いた後にあるファイル名まで移動したargvの 値が渡されています。 どうも、OpenBSD では、argv[k] が、0終端文字列が隙間無く並べら れている性質を利用しているようです。 argv[0],argv[1],argv[2],… "cmd名",0,"-opt1",0,"-opt2",0,…,"file1",0,"file2",0 途中の 0x00 を0x20(空白)に置き換えるだけなので、argsize は、 そのままのバイト数で良いからこのようなコードになっている ようです。4足しているのは"diff"という文字列のバイト数の分のようです。
| - UNIXプログラミング質問すれ Part10
658 :デフォルトの名無しさん[]:2014/05/31(土) 07:46:03.82 ID:6bjDZoIF - 【修正前】
void set_argstr(char **av, char **ave) { size_t argsize; char **ap; argsize = 4 + *ave - *av + 1; diffargs = xmalloc(argsize); strlcpy(diffargs, "diff", argsize); for (ap = av + 1; ap < ave; ap++) { if (strcmp(*ap, "--") != 0) { strlcat(diffargs, " ", argsize); strlcat(diffargs, *ap, argsize); } } }
| - UNIXプログラミング質問すれ Part10
659 :デフォルトの名無しさん[]:2014/05/31(土) 07:46:54.80 ID:6bjDZoIF - 【修正後】
void set_argstr(char **av, char **ave) { size_t argsize; char **ap; argsize = 4; // "diff" 文字列の長さ for (ap = av + 1; ap < ave; ap++) { argsize += 1 + strlen( *ap ); // 間の空白 + 引数の文字数 } argsize++; // 最後の NUL終端文字列 diffargs = xmalloc(argsize); strlcpy(diffargs, "diff", argsize); for (ap = av + 1; ap < ave; ap++) { if (strcmp(*ap, "--") != 0) { strlcat(diffargs, " ", argsize); strlcat(diffargs, *ap, argsize); } } }
| - UNIXプログラミング質問すれ Part10
660 :デフォルトの名無しさん[]:2014/05/31(土) 07:52:02.32 ID:6bjDZoIF - なお、エラー表示に「diff」が表示されているのは、argv[0]を使って
いるわけではなく、ライブラリの err() 関数が自分でやってるんですね。 av に argv が渡されているので混乱しそうですが、たまたまです。
|
|