要約すると:
- <リ>
/proc
の Unix の場合 本当にまっすぐで現実的な方法は:
- <リ>
readlink("/proc/self/exe", buf, bufsize)
(Linux)
readlink("/proc/curproc/file", buf, bufsize)
(FreeBSD)
readlink("/proc/self/path/a.out", buf, bufsize)
(Solaris)
/proc
のない Unix の場合 (つまり、上記が失敗した場合):
- <リ>
argv[0] が "/" (絶対パス) で始まる場合、これがパスです。
<リ>それ以外の場合、argv[0] に "/" (相対パス) が含まれている場合は、それを cwd に追加します (まだ変更されていないと仮定します)。
<リ>
それ以外の場合は、$PATH
のディレクトリを検索します 実行可能な argv[0]
の場合 .
その後、実行可能ファイルが実際にシンボリック リンクではないかどうかを確認するのが妥当な場合があります。シンボリック リンク ディレクトリに対して相対的に解決します。
/proc メソッドでは、この手順は必要ありません (少なくとも Linux の場合)。そこでは、proc シンボリック リンクが実行可能ファイルを直接指しています。
argv[0]
を設定するのは呼び出しプロセス次第であることに注意してください ほとんどの場合は正しいですが、呼び出しプロセスが信頼できない場合があります (例:setuid 実行可能ファイル)。
Windows の場合:GetModuleFileName(NULL, buf, bufsize)
を使用します
Windows を使用している場合は、GetModuleFileName() 関数を使用してください。
以下のコメントは UNIX 専用であることに注意してください。
この質問に対する衒学的な答えは、一般は存在しないということです。 すべてのケースでこの質問に正しく答える方法。お気づきのように、argv[0] は親プロセスによって任意に設定できるため、プログラムの実際の名前やファイル システム内の場所とはまったく関係がありません。
ただし、多くの場合、次のヒューリスティックが機能します:
<オール>/
が含まれている場合 、getcwd() で現在の作業ディレクトリを特定し、それに argv[0] を追加します。これらはすべて、問題のプログラムを呼び出したプロセスによって回避できることに注意してください。最後に、emg-2 で言及されているような Linux 固有の手法を使用できます。おそらく、他のオペレーティング システムにも同等の手法があります。
上記の手順で有効なパス名が得られたとしても、実際に必要なパス名が得られない可能性があります (実際にやりたいことは、どこかで構成ファイルを見つけることだと思うからです)。ハード リンクが存在するということは、次のような状況が発生する可能性があることを意味します:
-- assume /app/bin/foo is the actual program
$ mkdir /some/where/else
$ ln /app/bin/foo /some/where/else/foo # create a hard link to foo
$ /some/where/else/foo
さて、上記のアプローチ (おそらく /proc/$pid/exe を含む) は /some/where/else/foo
を返します。 プログラムへの実際のパスとして。実際、それは a です あなたが望んでいたものではなく、プログラムへの実際のパス。この問題は、実際にはハード リンクよりもはるかに一般的なシンボリック リンクでは発生しないことに注意してください。
このアプローチは原則として信頼できないという事実にもかかわらず、実際にはほとんどの目的に対して十分に機能します。