Как мне найти расположение исполняемого файла в C? [Дубликат]

Вы можете использовать playOrm, чтобы делать то, что хотите в одном запросе (с S-SQL масштабируемым SQL).

140
задан Peter Mortensen 16 October 2016 в 09:04
поделиться

8 ответов

Подводя итог:

  • В Unix с / proc действительно прямой и надежный способ:

    • readlink ("/ proc / self / exe", buf , bufsize) (Linux)

    • readlink ("/ proc / curproc / file", buf, bufsize) (FreeBSD)

    • readlink ("/ proc / self / path / a.out" , buf, bufsize) (Solaris)

  • В Unix без / proc (т. е. в случае ошибки выше):

    • Если argv [0] начинается с «/» (абсолютный путь), это - это путь.

    • В противном случае, если argv [0] содержит "/" (относительный путь), добавьте его в cwd (assuming it hasn't been changed yet).

    • Otherwise search directories in $PATH for executable argv[0].

    Afterwards it may be reasonable to check whether the executable isn't actually a symlink. If it is resolve it relative to the symlink directory.

    This step is not necessary in /proc method (at least for Linux). There the proc symlink points directly to executable.

    Note that it is up to the calling process to set argv[0] correctly. It is right most of the times however there are occasions when the calling process cannot be trusted (ex. setuid executable).

  • On Windows: use GetModuleFileName(NULL, buf, bufsize)

189
ответ дан 23 November 2019 в 23:15
поделиться

Используйте функцию GetModuleFileName () , если вы используете Windows.

22
ответ дан 23 November 2019 в 23:15
поделиться

Помните, что в системах Unix двоичный файл мог быть удален с момента его запуска. Это совершенно законно и безопасно в Unix. Последний раз я проверял, что Windows не позволит вам удалить работающий двоичный файл.

/ proc / self / exe по-прежнему будет доступен для чтения, но на самом деле это не будет рабочая символическая ссылка. Это будет ... странно.

4
ответ дан 23 November 2019 в 23:15
поделиться

Во многих системах POSIX вы можете проверить simlink, расположенный в / proc / PID / exe. Несколько примеров:

# file /proc/*/exe
/proc/1001/exe: symbolic link to /usr/bin/distccd
/proc/1023/exe: symbolic link to /usr/sbin/sendmail.sendmail
/proc/1043/exe: symbolic link to /usr/sbin/crond
6
ответ дан 23 November 2019 в 23:15
поделиться

Please note that the following comments are unix-only.

The pedantic answer to this question is that there is no general way to answer this question correctly in all cases. As you've discovered, argv[0] can be set to anything at all by the parent process, and so need have no relation whatsoever to the actual name of the program or its location in the file system.

However, the following heuristic often works:

  1. If argv[0] is an absolute path, assume this is the full path to the executable.
  2. If argv[0] is a relative path, ie, it contains a /, determine the current working directory with getcwd() and then append argv[0] to it.
  3. If argv[0] is a plain word, search $PATH looking for argv[0], and append argv[0] to whatever directory you find it in.

Note that all of these can be circumvented by the process which invoked the program in question. Finally, you can use linux-specific techniques, such as mentioned by emg-2. There are probably equivalent techniques on other operating systems.

Even supposing that the steps above give you a valid path name, you still might not have the path name you actually want (since I suspect that what you actually want to do is find a configuration file somewhere). The presence of hard links means that you can have the following situation:

-- 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

Now, the approach above (including, I suspect, /proc/$pid/exe) will give /some/where/else/foo as the real path to the program. And, in fact, it is a real path to the program, just not the one you wanted. Note that this problem doesn't occur with symbolic links which are much more common in practice than hard links.

In spite of the fact that this approach is in principle unreliable, it works well enough in practice for most purposes.

17
ответ дан 23 November 2019 в 23:15
поделиться

На самом деле это не ответ, а просто примечание, которое следует иметь в виду.

Как мы могли видеть, проблема определения местоположения исполняемого файла в Linux довольно сложна и зависит от платформы. и Unix. Прежде чем делать это, следует дважды подумать.

Если вам нужно место для исполняемого файла для обнаружения некоторых файлов конфигурации или ресурсов, возможно, вам следует следовать способу размещения файлов в системе Unix: поместите конфигурации в / etc или / usr / local / etc или в домашнем каталоге текущего пользователя, а / usr / share - хорошее место для размещения файлов ресурсов.

10
ответ дан 23 November 2019 в 23:15
поделиться

Я бы

1) Используйте функцию basename (): http://linux.die.net/man/3/basename
2) chdir () в этот каталог
3) Используйте getpwd (), чтобы получить текущий каталог

. Таким образом вы получите каталог в аккуратной, полной форме вместо ./ или ../bin/.

. Возможно, вы захотите сохранить и восстановите текущий каталог, если это важно для вашей программы.

0
ответ дан 23 November 2019 в 23:15
поделиться

Для Linux вы можете найти способ / proc / self / exe , связанный с хорошей библиотекой binreloc, вы можете найти библиотеку по адресу:

3
ответ дан 23 November 2019 в 23:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: