La réponse acceptée est presque correcte, sauf que vous ne pouvez pas compter sur PATH_MAX car c'est
pas garanti d'être défini par POSIX si le système n'a pas une telle limite.
(De la page de manuel readlink(2))
De plus, lorsqu'elle est définie, elle ne représente pas toujours la "vraie" limite. (Voir http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html )
La page de manuel de readlink donne également un moyen de le faire sur le lien symbolique :
L'utilisation d'un tampon de taille statique peut ne pas fournir suffisamment d'espace pour le contenu du lien symbolique. La taille requise pour le tampon peut être obtenue à partir de la valeur stat.st_size renvoyée par un appel à lstat(2) sur le lien. Cependant, le nombre d'octets écrits par readlink() et read‐linkat() doit être vérifié pour s'assurer que la taille du lien symbolique n'a pas augmenté entre les appels.
Cependant, dans le cas de /proc/self/exe/ comme pour la plupart des fichiers /proc, stat.st_size serait 0. La seule solution restante que je vois est de redimensionner le tampon tant qu'il ne rentre pas.
Je suggère l'utilisation de vector<char>
comme suit à cet effet :
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 "";
}
Utilisez correctement la fonction readlink() pour les utilisations correctes du readlink
fonction.
Si vous avez votre chemin dans un std::string
, vous pourriez faire quelque chose comme ceci :
#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 */
}
Si vous recherchez uniquement un chemin fixe :
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 */
}
Pour l'utiliser :
int main()
{
std::string selfpath = get_selfpath();
std::cout << selfpath << std::endl;
return 0;
}
Regardons ce que dit la page de manuel :
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.
D'ACCORD. Devrait être assez simple. Étant donné votre tampon de 1024 caractères :
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;
}