C言語にて 実行中のプログラムのファイルパスを取得する

Linux

Linux では、 実行中のプログラムのシンボリックリンクが、 /proc/pid/exe にある。 これを readlink で読むと、ファイルパスが得られる

char path[PATH_MAX + 1];

const size_t LINKSIZE = 100;
char link[LINKSIZE];

// 実行中のプロセスのシンボリックリンク
snprintf(link, LINKSIZE, "/proc/%d/exe", getpid() );

// ファイルパスが得る
readlink( link, path, PATH_MAX);

参考 : C/C++ - executable path
https://stackoverflow.com/questions/8579065/c-c-executable-path

macOS

macOS では、ファイルパスを取得する API _NSGetExecutablePath が用意されている

Mac OS X Man Pages
https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dyld.3.html

uint32_t bufsize = PATH_MAX;
char buf[PATH_MAX];
  
_NSGetExecutablePath(buf, &bufsize);

参考 : Programmatically retrieving the absolute path of an OS X command-line app https://stackoverflow.com/questions/799679/programmatically-retrieving-the-absolute-path-of-an-os-x-command-line-app/1024933#1024933

コマンド名を削除する

上記の方法で得られるパス名は、コマンド名を含む下記のようなもの

/home/user/hoge/./a.out

これからコマンド名を削除して、下記のようなディレクトリのパス名にする。

/home/user/hoge/

コマンド名は manin 関数の引数から取得できる。
argv[0] がコマンド名。

str_replace は文字列を置換する関数
https://ken-ohwada.hatenadiary.org/entry/2021/01/03/114140

```` int main(int argc, char *argv[]) { char path[PATH_MAX];

getExecutablePath( (char *)path );

char dir[100];

str_replace(path, cmd, "", dir );

} ````

サンプルコードは githubに公開した https://github.com/ohwada/MAC_cpp_Samples/tree/master/system/c_src