Как найти местоположение исполняемого файла в Linux, когда обычные методы терпят неудачу?
Вопрос
В другом вопросе в ответе указано, что в Unix-файлах с /proc
, действительно прямой и надежный способ - это readlink("/proc/self/exe", buf, bufsize)
и затем он переходит к предоставлению решений для резервного копирования следующим образом:
В Unix - файлах без /proc (т.е.если вышеописанный сбой):
- Если argv[0] начинается с "/" (абсолютный путь), это и есть путь.
- В противном случае, если argv[0] содержит "/" (относительный путь), добавьте его в cwd (при условии, что он еще не был изменен).
getcwd(buf, bufsize); strncat(buf, "/", bufsize-strlen(buf)-1); strncat(buf, argv[0], bufsize-strlen(buf)-1);
- В противном случае ищите каталоги в
$PATH
для исполняемогоargv[0]
.
После этого может быть разумно проверить, не является ли исполняемый файл на самом деле символической ссылкой.Если это так, разрешите это относительно каталога символических ссылок.
Теперь в моем случае, к сожалению, ничего из вышеперечисленного не работает:
/proc/self/exe exists
но не в состоянииreadlink()
из-за отказа в разрешении ошибка 13.- В
argv[0]
не имеет/
для абсолютного или относительного пути. - В
$PATH
не содержит исполняемый файл , найденный вargv[0]
.
Похоже, с этой проблемой сталкиваются также при запуске приложений sgid.В моем случае это не sgid, а запуск inetd.
Решение
Попробуйте поискать в /proc из двоичного файла suid.
Другие советы
Лучший способ решить эту проблему - в файле конфигурации /etc /xinetd.d / MyApp добавить переменную среды, которая определяет местоположение двоичного файла следующим образом:
service myApp
{
socket_type = stream
protocol = tcp
wait = no
user = root
server = /usr/local/bin/myAppd
env = MY_APP_HOME=/usr/local/bin
port = 2354
disable = no
}
Затем, если в разрешении /proc/self /exe отказано, проверьте наличие переменной env и используйте ее вместо этого.
Я думаю, что ответ таков:сдавайся.
Попросите пользователя передать каталог установки (или что бы вы ни искали) в качестве аргумента командной строки.
В качестве последнего средства проанализируйте файл /etc/xinetd.d/MyApp, чтобы извлечь строку сервера, которая включает полный путь к исполняемому файлу, вызванному через inetd.