如何实现readlink来查找路径

a s*_*ich 21 c++ linux executable path

使用readlink函数作为解决方案如何在C中找到可执行文件的位置?,我如何将路径转换为char数组?此外,变量buf和bufsize代表什么,我如何初始化它们?

编辑:我正在尝试获取当前正在运行的程序的路径,就像上面链接的问题.这个问题的答案说要用readlink("proc/self/exe").我不知道如何在我的程序中实现它.我试过了:

char buf[1024];  
string var = readlink("/proc/self/exe", buf, bufsize);  
Run Code Online (Sandbox Code Playgroud)

这显然是不正确的.

Mat*_*Mat 37

这正确使用readlink()函数以正确使用该readlink函数.

如果你的路径是a std::string,你可以这样做:

#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 */
}
Run Code Online (Sandbox Code Playgroud)

如果你只是在固定路径之后:

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 */
}
Run Code Online (Sandbox Code Playgroud)

要使用它:

int main()
{
  std::string selfpath = get_selfpath();
  std::cout << selfpath << std::endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)


Wdd*_*ysr 5

接受的答案几乎是正确的,除非您不能依赖 PATH_MAX,因为它是

如果系统没有这样的限制,则不能保证按 POSIX 定义。

(来自 readlink(2) 联机帮助页)

此外,当它被定义时,它并不总是代表“真实”的限制。(见http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html

readlink 的联机帮助页还提供了一种在 symlink 上执行此操作的方法:

使用静态大小的缓冲区可能无法为符号链接内容提供足够的空间。缓冲区所需的大小可以从在链接上调用 lstat(2) 返回的 stat.st_size 值获得。但是,readlink() 写入和读取的字节数是多少?应检查 linkat() 以确保符号链接的大小在调用之间没有增加。

但是,在 /proc/self/exe/ 的情况下,对于大多数 /proc 文件,stat.st_size 将为 0。我看到的唯一剩余解决方案是在不适合的情况下调整缓冲区大小。

vector<char>为此,我建议使用以下方法:

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 "";
}
Run Code Online (Sandbox Code Playgroud)