トップページ > プログラム > 2014年05月31日 > 6bjDZoIF

書き込み順位&時間帯一覧

12 位/205 ID中時間01234567891011121314151617181920212223Total
書き込み数0000000400000000000000004



使用した名前一覧書き込んだスレッド一覧
デフォルトの名無しさん
UNIXプログラミング質問すれ Part10

書き込みレス一覧

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 が渡されているので混乱しそうですが、たまたまです。


※このページは、『2ちゃんねる』の書き込みを基に自動生成したものです。オリジナルはリンク先の2ちゃんねるの書き込みです。
※このサイトでオリジナルの書き込みについては対応できません。
※何か問題のある場合はメールをしてください。対応します。