Přijatá odpověď je téměř správná, kromě toho, že se nemůžete spolehnout na PATH_MAX, protože je
není zaručeno, že bude definován podle POSIX, pokud systém takový limit nemá.
(Z manuálové stránky readlink(2))
Také, když je definován, ne vždy představuje "skutečný" limit. (Viz http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html )
Manuálová stránka readlinku také poskytuje způsob, jak to udělat na symbolickém odkazu:
Použití vyrovnávací paměti statické velikosti nemusí poskytnout dostatek místa pro obsah symbolického odkazu. Požadovanou velikost vyrovnávací paměti lze získat z hodnoty stat.st_size vrácené voláním lstat(2) na odkazu. Je však třeba zkontrolovat počet bajtů zapsaných funkcemi readlink() a read‐linkat(), abyste se ujistili, že se velikost symbolického odkazu mezi voláními nezvětšila.
Nicméně v případě /proc/self/exe/ jako u většiny souborů /proc by stat.st_size byla 0. Jediné řešení, které vidím, je změnit velikost vyrovnávací paměti, dokud se nevejde.
Doporučuji použít vector<char>
pro tento účel:
std::string get_selfpath()
{
std::vector<char> buf(400);
ssize_t len;
do
{
buf.resize(buf.size() + 100);
len = ::readlink("/proc/self/exe", &(buf[0]), buf.size());
} while (buf.size() == len);
if (len > 0)
{
buf[len] = '\0';
return (std::string(&(buf[0])));
}
/* handle error */
return "";
}
Toto Používejte správně funkci readlink() pro správné použití readlink
funkce.
Pokud máte cestu v std::string
, můžete udělat něco takového:
#include <unistd.h>
#include <limits.h>
std::string do_readlink(std::string const& path) {
char buff[PATH_MAX];
ssize_t len = ::readlink(path.c_str(), buff, sizeof(buff)-1);
if (len != -1) {
buff[len] = '\0';
return std::string(buff);
}
/* handle error condition */
}
Pokud hledáte pouze pevnou cestu:
std::string get_selfpath() {
char buff[PATH_MAX];
ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1);
if (len != -1) {
buff[len] = '\0';
return std::string(buff);
}
/* handle error condition */
}
Chcete-li jej použít:
int main()
{
std::string selfpath = get_selfpath();
std::cout << selfpath << std::endl;
return 0;
}
Podívejme se, co říká manuálová stránka:
readlink() places the contents of the symbolic link path in the buffer
buf, which has size bufsiz. readlink does not append a NUL character to
buf.
OK. Mělo by to být dostatečně jednoduché. Vzhledem k vaší vyrovnávací paměti 1024 znaků:
char buf[1024];
/* The manpage says it won't null terminate. Let's zero the buffer. */
memset(buf, 0, sizeof(buf));
/* Note we use sizeof(buf)-1 since we may need an extra char for NUL. */
if (readlink("/proc/self/exe", buf, sizeof(buf)-1) < 0)
{
/* There was an error... Perhaps the path does not exist
* or the buffer is not big enough. errno has the details. */
perror("readlink");
return -1;
}