パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

argv[0]は何をさしているか?」記事へのコメント

  • エキスパートCプログラミング―知られざるCの深層 (Ascii books) (単行本) [amazon.co.jp]

    いや、実は仕様だから。

    仕様として「引数はスタックアルゴリズムを使って、後ろの引数が省略可能であるような順序で積み上げる事」になっているから。つまり一応 main(argc)も作れるには作れる。意味があるとは思えないが。main()を呼ぶ側は、必ず main(argc,argv,env)のように呼び出す必要がある。

    本当に Stack に積み上げてもいいが、スタックが無いプロセッサと言うものもこの世にはあり、そういう環境用のCコンパイラも存在するので「スタック上にこう積み上げているから」という答は正解ではない。
    # だいたい、それだとレ
    --
    fjの教祖様
    • いやはや正解だと思っていた、スタックという答えは見事に粉砕されました。
      引数のレジスタ渡しというのがありましたね。

      openについてですが、fopenしか使った事が無かったので戸惑いましたが、
      マニュアルを読むと、

      http://www.linux.or.jp/JM/html/LDP_man-pages/man2/open.2.html [linux.or.jp]

      printfとほぼ同じ実装のようですね。可変長引数の関数として定義されて
      いて、第二引数flagでO_CREATが指定された場合のみ、第三引数modeが
      参照される。glibcのソースコードでも確認しましたが、そのようになって
      いました。
      親コメント
      • printfとほぼ同じ実装のようですね。可変長引数の関数として定義されて
        いて、第二引数flagでO_CREATが指定された場合のみ、第三引数modeが
        参照される。

        その通りです。が、ここに問題があるのは見つけましたか?

        glibcは通常の関数コールからシステムコールへと変換するライブラリの所で、O_CREATチェックをして mode を0で渡すか、第3引数のある『はずの』所からデータを取ってくるかを決定しますよね?

        呼び出し側が O_CREATオプションつきで open() を呼んでおきながら、modeを渡し忘れた場合、mode にはゴミが入ってしまいます。

        つまり、「呼ばれた側は、厳密には mode の有無をチェックしておらず、ここに問題が起こる余地がある」って事です。誰だ、こんなのをPOSIX標準とした奴は…。拡張するなら creat(2)の方に「存在した場合の処理」を埋め込めばいいものを…。
        --
        fjの教祖様
        親コメント
        • それでしたら、openよりscanf/printfの方が深刻ではないですか? openは滅多に使わないし。私はopenを使った記憶が無い。いや、ソケットプログラムの習作で使ったかな?

          scanf/printf達はもうちょっとどうにかならんのかというような関数達です。gccなら文字列部分を解析してくれる機能もありますが、文字列定数として与えられている場合だけですしね。
          親コメント
          • scanf(3), printf(3)とopen(2)の違いは…物凄く乱暴に言うとprintf(3)達は「ライブラリ」に過ぎない。悪影響を与える範囲はそのプロセス内にとどまっている。

            ところが、open(2)は「システムコール」。つまり、glibcのopen()関数は、その引数を「カーネルに」引き継ぐ。「creat(2)時のmodeなんて被害はタカが知れている」かもしれないが、その被害は kernel の制御範囲全体に広がってしまう。ここが被害が甚大なポイント。

            .

            open(2)自体は…ようするにFILE構造体がもたらす「副作用」が困る場合に使います。同期書き込みがやりたいとか、ファイル開く程度でいちいちmalloc()して数メガもバッファとるな、どうせこちとら1kbyte程度も書かねぇ、とか…そういう場合。

            あと「排他的にファイルを開きたい」場合。flags に (O_CREAT|O_EXCL) が設定してあると「もし、そのファイルが無かったらファイルを作りなさい。そして排他的に開きなさい」と言うことになります。つまりそのファイルが存在している間は誰もそのファイルを作り直せないし開けない。いちいち共有メモリ等を作らずにプロセス間排他制御をしたいときに使いますが、これは fopen(3)では作れない。

            .

            ちなみに。
            ps の技。全てのunix系で使えるわけではありません。当然非unix系ではもっと使えない可能性が大きいです。

            なによりも argv[0]の先にあるメモリ領域のサイズによっては、buffer overflow を起こしかねません。起動時のファイル名が"abiraunkensovaka"とか長くて、statusが「0001」程度の長さならOKですが、逆の場合は危険なので、一般的な利用はやめましょう。100時間動かしたあとにこいつのせいでSIGSEGVを食らったときの衝撃は、忘れたくても忘れられないものです。
            --
            fjの教祖様
            親コメント

私は悩みをリストアップし始めたが、そのあまりの長さにいやけがさし、何も考えないことにした。-- Robert C. Pike

処理中...