Без доступа к argv[0], как я могу получить имя программы?
Я знаю, что имя программы передается в качестве первого аргумента, и следующий простой пример выведет его на стандартный вывод:
#include <iostream>
int main ( int argc, char *argv[] )
{
std::cout<<argv[0]<<std::endl;
}
Существует ли функция для получения имени программы?
EDIT
Я запускаю программу из оболочки, и приведенный выше код всегда будет печатать имя программы (я использую fedora 9, но я уверен, что он работает в других дистрибутивах).
Я обнаружил, что каталог /proc/self/ может содержать то, что я ищу, но я не смог найти что именно в этом справочнике.
6 ответов:
Нет, такой функции не существует. Linux хранит имя программы в
__progname, но это не публичный интерфейс. Если вы хотите использовать его для предупреждений / сообщений об ошибках, используйте функцииerr(3).Если вам нужен полный путь запущенной программы, вызовите
readlinkon/proc/self/exe:char *program_path() { char *path = malloc(PATH_MAX); if (path != NULL) { if (readlink("/proc/self/exe", path, PATH_MAX) == -1) { free(path); path = NULL; } } return path; }(я полагаю, что
__prognameимеет базовое имяargv[0]. Проверьте источники glibc, чтобы быть уверенным.)
Это не гарантируется.
Обычно
Одним словом: не полагайтесь на это.argv[0]содержит имя исполняемого файла, но можно вызвать исполняемый файл с помощьюexecveи установить его на что-то другое.
Нет, это зависитполностью от того, что родительская программа помещает туда.
Семейство функций
execпозволяет исполняемому имени полностью отличаться от передаваемого аргумента, и это поддерживается стандартом ISO C.Если значение argc больше нуля, строка, на которую указывает argv[0], представляет имя программы; argv[0][0] будет нулевым символом, если имя программы недоступно из среды хоста.
Так что нет., это только название программы, если оно доступно. А в предыдущем разделе говорится:
Если значение argc больше нуля, то элементы массива argv[0] через argv [argc-1] включительно должны содержать указатели на строки, которые задаютсязначениями, определенными реализацией средой хоста до запуска программы.
(Курсив мой).
Таким образом, даже их значения не диктуются стандартом, это полностью зависит от реализации. Этот означает, что имя программы может быть пустым, если среда хоста не предоставляет его, и ничего другого, если среда хоста предоставляет его.Тем не менее, определение реализации имеет особое значение в стандартах ИСО-реализациядолжна документировать, как она работает. Так что даже UNIX, который может поместить все, что угодно, в
argv[0]с семейством вызововexec, должен (и делает) документировать это.Аналогично (благодаря Chubsdad), C++03 утверждает:
Таким образом, даже там argv[0] может ничего не содержать и, даже если это так, "представляет имя" является очень расплывчатым требованием. Это не обязательно должен быть полный путь к исполняемому файлу или даже содержать команду, используемую для его вызова" Если argc является ненулевые эти аргументы должны подаваться в argv[0] через argv[argc-1] в качестве указателей на начальные символы многобайтовых строк с нулевым завершением (NTMBSs) (17.3.2.1.3.2), а argv[0] должен быть указателем на начальный символ NTMBS, представляющий имя, используемое для вызова программы или "".
Другой способ сделать это в Linux-с помощью файловой системы
proc. Я думаю, что/proc/self/exe- это ссылка на исполняемый файл.В Википедии есть запись для
procfsфайловая система с большим количеством вкусностей.
Решение, специфичное для GLIBC:
#include <errno.h> ... fprintf(stderr, "Program name is %s\n", program_invocation_name);Из
man invocation_name:
program_invocation_nameсодержит имя, которое было использовано для вызова вызывающей программы. Это то же самое, что и значениеargv[0]вmain(), с той разницей, что область действияprogram_invocation_nameявляется глобальной.
program_invocation_short_nameсодержит компонент basename имени, который использовался для вызова вызывающей программы. То есть это то же самое значение, что иprogram_invocation_name, с удалением всего текста вплоть до последней косой черты ( / ), если таковая имеется.
Вы можете определить pid вашего процесса с помощью getpid (), а затем проверить содержимое /proc/[PID number] с помощью стандартных инструментов ввода-вывода.
Если вы используете GLib, вы можете использовать функцию
g_get_prgname(). На Win32 он звонитGetModuleFileNameW(), на всем остальном он, кажется, возвращает NULL, хотя.
Comments