最初の if 文は、引数の数(argc)が argv の中で次に処理されるべき要素を示すインデックス(optind)以下の場合に実行される、ということで、典型的には yes(1) が引数無しで呼ばれたときに if 文の中に入る。if 文の bad_cast() は、src/system.h で定義されていて、const char * を引数にして、char * で返す関数。const だったものを強引に const 外すから、bad_ なのかな。75 if (argc <= optind) 76 { 77 optind = argc; 78 argv[argc++] = bad_cast ("y"); 79 } 80 81 for (;;) 82 { 83 int i; 84 for (i = optind; i < argc; i++) 85 if (fputs (argv[i], stdout) == EOF 86 || putchar (i == argc - 1 ? '\n' : ' ') == EOF) 87 { 88 error (0, errno, _("standard output")); 89 exit (EXIT_FAILURE); 90 } 91 }
次の while 文が、yes(1) の出力処理を実行してる。argv の optind から順に fputs していって、最後の要素を fputs したら改行文字を putchar(3) する。というわけで、
のように実行すると、"a b c" が出力されるわけだ。
$ yes a b c
$ yesみたく、引数がない場合は、argv[optind] に "y" が設定されるから、"y" が連続して出力される。
この yes.c を読んで気になったのは、78行目、
の部分。これ、メモリ破壊起こすんじゃないのかな....argv の要素数は argc で与えられているわけで、argv[argc] は与えられた領域を超えちゃってるような。ググって調べてみたけど、78行目みたいなことができる根拠がわからなかった。。誰か教えて!!78 argv[argc++] = bad_cast ("y");
argc <= optind になる場合とか、そのほかいろんな制約がわかってないけど、たとえば、↓のようになってればすっきりするんだけど。。
@@ -74,8 +74,8 @@ま、いいやっ!
if (argc <= optind)
{
- optind = argc;
- argv[argc++] = bad_cast ("y");
+ optind = argc - 1;
+ argv[optind] = bad_cast ("y");
}
0 件のコメント:
コメントを投稿