La risposta accettata è quasi corretta, tranne per il fatto che non puoi fare affidamento su PATH_MAX perché lo è
non garantito per essere definito per POSIX se il sistema non ha tale limite.
(Dalla pagina man di readlink(2))
Inoltre, quando è definito non sempre rappresenta il limite "vero". (Vedi http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html )
La manpage di readlink fornisce anche un modo per farlo su symlink :
L'utilizzo di un buffer di dimensioni statiche potrebbe non fornire spazio sufficiente per il contenuto del collegamento simbolico. La dimensione richiesta per il buffer può essere ottenuta dal valore stat.st_size restituito da una chiamata a lstat(2) sul collegamento. Tuttavia, il numero di byte scritti da readlink() e read‐linkat() dovrebbe essere controllato per assicurarsi che la dimensione del collegamento simbolico non sia aumentata tra le chiamate.
Tuttavia, nel caso di /proc/self/exe/ come per la maggior parte dei file /proc, stat.st_size sarebbe 0. L'unica soluzione rimanente che vedo è ridimensionare il buffer mentre non si adatta.
Suggerisco l'uso di vector<char>
come segue per questo scopo:
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 "";
}
Usa correttamente la funzione readlink() per gli usi corretti di readlink
funzione.
Se hai il tuo percorso in un std::string
, potresti fare qualcosa del genere:
#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 */
}
Se cerchi solo un percorso prestabilito:
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 */
}
Per usarlo:
int main()
{
std::string selfpath = get_selfpath();
std::cout << selfpath << std::endl;
return 0;
}
Diamo un'occhiata a cosa dice la manpage:
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. Dovrebbe essere abbastanza semplice. Dato il tuo buffer di 1024 caratteri:
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;
}