LINUX.ORG.RU

Как программе узнать где она лежит ?


0

0

Подскажите способ определить из программы где она лежит, не откуда она была запущена, а где лежит. Чувствую что есть простой способ, пока пришлось заюзать следующее:

progman@prealfa:/tmp/ddd$ cat test.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

int main()
{
char buf[1024];
sprintf (buf, "/proc/%lu/exe", getpid());
int rc = readlink(buf, buf, sizeof(buf));
if (rc == -1)
{
printf ("ERROR: %s\n", strerror(errno));
exit(1);
}

buf[rc] = 0;
printf ("%s\n", buf);

return 0;
}

progman@prealfa:/tmp/ddd$ g++ test.cpp -o test
progman@prealfa:/tmp/ddd$ ./test
/tmp/ddd/test


Как проще ?!!

> Как проще ?!!

не думаю, что можно проще. разве что вот это:

   sprintf (buf, "/proc/%lu/exe", getpid());
   int rc = readlink(buf, buf, sizeof(buf));

можно чуток упростить:

   int rc = readlink("/proc/self/exe", buf, sizeof(buf));

idle ★★★★★
()
Ответ на: комментарий от idle

Жаль если нельзя проще. На той-же солярке это не пойдет...

linuxsoft
() автор топика

> Как проще ?!!

canonicalize_file_name(argv[0]) должно служить хорошей отправной точкой для дальнейших исследований ;)

anonymous
()
Ответ на: комментарий от linuxsoft

> Это путь откуда программа была запущена а не где она лежит

Похоже, я не улавливаю разницы.

Если под "откуда программа была запущена" понимается текущий каталог, то утверждение неверно. Если речь идет о символических ссылках, то да, его можно назвать верным ... вот только где лежит программа на котурую есть больше одного hard link'а ?

anonymous
()
Ответ на: комментарий от anonymous

hard link не интересуют. Есть скажем программа super_test лежит она в каталоге /usr/local/bin. Мне нужно чтобы при ее запуске она всегда понимала что лежит она в /usr/local/bin, вне зависимости от того как ее запустили.
Так: cd /tmp; super_test
Или так: cd /usr/local/bin; ./super_test

Нужно это для информационных целей (записи в log) чтобы было ясно программу из какого каталога запустили.

linuxsoft
() автор топика
Ответ на: комментарий от linuxsoft

Не, я имел в виду, что argv[0] может быть любым, не только строкой запуска программы.

unnamed
()
Ответ на: комментарий от linuxsoft

> cd /usr/local/bin; ./super_test

а в чем проблемы? argv[0] + current dir:
/usr/local/bin/super_test

после того как получил абсолютный путь, смотриш является ли
файл симлинком, если да то смотриш на что он указывает


aton
()
Ответ на: комментарий от aton

> а в чем проблемы? argv[0] + current dir:

ну ведь unnamed уже несколько раз сказал, чтo argv[0]
может быть ЛЮБЫМ, даже NULL, если хотите:

        execl("/path/prog", NULL);

argv[0] будет 0.

idle ★★★★★
()
Ответ на: комментарий от linuxsoft

> Нужно это для информационных целей (записи в log) чтобы было ясно программу из какого каталога запустили.

Если при запуске программы не использовались всякие извраты (вроде того, какой описал выше idle), то вот портабельный способ узнать, откуда запущена программа:

FILE *fp;
setenv(prg, argv[0], 1);
fp = popen("which $prg", "r");
/* здесь читаем из fp полное имя программы */

nobody ★★
()
Ответ на: комментарий от nobody

>fp = popen("which $prg", "r");

Подключение which - не самый лучший способ.

unnamed
()

Кошерный способ из Advanced Linux Programming. Почти как у автора.

Listing 7.5 (get-exe-path.c) Get the Path of the Currently Running Program Executable
------------------------------------------------------------------
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/* Finds the path containing the currently running program executable.
The path is placed into BUFFER, which is of length LEN. Returns
the number of characters in the path, or -1 on error. */
size_t get_executable_path (char* buffer, size_t len)
{
char* path_end;
/* Read the target of /proc/self/exe. */
if (readlink (&#8220;/proc/self/exe&#8221;, buffer, len) <= 0)
return -1;
/* Find the last occurrence of a forward slash, the path separator. */
path_end = strrchr (buffer, &#8216;/&#8217;);
if (path_end == NULL)
return -1;
/* Advance to the character past the last slash. */
++path_end;
/* Obtain the directory containing the program by truncating the
path after the last slash. */
*path_end = &#8216;\0&#8217;;
/* The length of the path is the number of characters up through the
last slash. */
return (size_t) (path_end - buffer);
}
int main ()
{
char path[PATH_MAX];
get_executable_path (path, sizeof (path));
printf (&#8220;this program is in the directory %s\n&#8221;, path);
return 0;
}

grob ★★★★★
()

гыгы, в проге открыть файл, лежащий(при установке складывать) с этойже прогой в одной дире, например конфиг, потом сказать lsof

vilfred ☆☆
()
Ответ на: комментарий от vilfred

>гыгы, в проге открыть файл, лежащий(при установке складывать) с этойже >прогой в одной дире, например конфиг, потом сказать lsof
По десятому кругу пошли, в какой "в одной" ? :))

anonymous
()
Ответ на: комментарий от anonymous

tar -zxvf *.tar.gz ./configure make

все сложится в текущую директорию

tar -zxvf *.tar.gz ./configure make make install

все сложится в определенную директорию для всех юзверей и все.

vilfred ☆☆
()
Ответ на: комментарий от vilfred

Если всё сложится в определённую директорию, тогда теряется смысл определения, где лежит программа:))) ведь это уже известно!

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.