如何实现readlink查找路径

时间:2022-02-25 13:16:44

Using the readlink function used as a solution to How do I find the location of the executable in C?, how would I get the path into a char array? Also, what do the variables buf and bufsize represent and how do I initialize them?

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

EDIT: I am trying to get the path of the currently running program, just like the question linked above. The answer to that question said to use readlink("proc/self/exe"). I do not know how to implement that into my program. I tried:

编辑:我正在尝试获取当前正在运行的程序的路径,就像上面链接的问题一样。这个问题的答案是使用readlink(“proc/self/exe”)。我不知道如何在我的程序中实现它。我试着:

char buf[1024];  
string var = readlink("/proc/self/exe", buf, bufsize);  

This is obviously incorrect.

这显然是不正确的。

4 个解决方案

#1


33  

This Use the readlink() function properly for the correct uses of the readlink function.

这将正确地使用readlink()函数来正确地使用readlink函数。

If you have your path in a std::string, you could do something like this:

如果您在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 */
}

If you're only after a fixed path:

如果你只是走了一条固定的路:

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 */
}

To use it:

使用它:

int main()
{
  std::string selfpath = get_selfpath();
  std::cout << selfpath << std::endl;
  return 0;
}

#2


4  

Let's look at what the manpage says:

让我们看看手册是怎么说的:

 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. Should be simple enough. Given your buffer of 1024 chars:

好的。应该很简单。假设你的缓冲区为1024个字符:

 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;
 }

#3


1  

char *
readlink_malloc (const char *filename)
{
  int size = 100;
  char *buffer = NULL;

  while (1)
    {
      buffer = (char *) xrealloc (buffer, size);
      int nchars = readlink (filename, buffer, size);
      if (nchars < 0)
        {
          free (buffer);
          return NULL;
        }
      if (nchars < size)
        return buffer;
      size *= 2;
    }
}

Taken from: http://www.delorie.com/gnu/docs/glibc/libc_279.html

来自:http://www.delorie.com/gnu/docs/glibc/libc_279.html

#4


1  

Accepted answer is almost correct, except you can't rely on PATH_MAX because it is

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

not guaranteed to be defined per POSIX if the system does not have such limit.

如果系统没有这样的限制,就不能保证每个POSIX都有定义。

(From readlink(2) manpage)

(从指向(2)从)

Also, when it's defined it doesn't always represent the "true" limit. (See http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html )

而且,当它被定义时,它并不总是代表“真”极限。(参见http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html)

The readlink's manpage also give a way to do that on symlink :

readlink的manpage也给出了一个在symlink上做这个的方法:

Using a statically sized buffer might not provide enough room for the symbolic link contents. The required size for the buffer can be obtained from the stat.st_size value returned by a call to lstat(2) on the link. However, the number of bytes written by readlink() and read‐ linkat() should be checked to make sure that the size of the symbolic link did not increase between the calls.

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

However in the case of /proc/self/exe/ as for most of /proc files, stat.st_size would be 0. The only remaining solution I see is to resize buffer while it doesn't fit.

然而,对于大多数/proc文件来说,state .st_size将是0。我看到的唯一的解决方案是在缓冲区不适合时调整缓冲区的大小。

I suggest the use of vector<char> as follow for this purpose:

为此,我建议使用向量 :

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 "";
}

#1


33  

This Use the readlink() function properly for the correct uses of the readlink function.

这将正确地使用readlink()函数来正确地使用readlink函数。

If you have your path in a std::string, you could do something like this:

如果您在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 */
}

If you're only after a fixed path:

如果你只是走了一条固定的路:

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 */
}

To use it:

使用它:

int main()
{
  std::string selfpath = get_selfpath();
  std::cout << selfpath << std::endl;
  return 0;
}

#2


4  

Let's look at what the manpage says:

让我们看看手册是怎么说的:

 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. Should be simple enough. Given your buffer of 1024 chars:

好的。应该很简单。假设你的缓冲区为1024个字符:

 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;
 }

#3


1  

char *
readlink_malloc (const char *filename)
{
  int size = 100;
  char *buffer = NULL;

  while (1)
    {
      buffer = (char *) xrealloc (buffer, size);
      int nchars = readlink (filename, buffer, size);
      if (nchars < 0)
        {
          free (buffer);
          return NULL;
        }
      if (nchars < size)
        return buffer;
      size *= 2;
    }
}

Taken from: http://www.delorie.com/gnu/docs/glibc/libc_279.html

来自:http://www.delorie.com/gnu/docs/glibc/libc_279.html

#4


1  

Accepted answer is almost correct, except you can't rely on PATH_MAX because it is

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

not guaranteed to be defined per POSIX if the system does not have such limit.

如果系统没有这样的限制,就不能保证每个POSIX都有定义。

(From readlink(2) manpage)

(从指向(2)从)

Also, when it's defined it doesn't always represent the "true" limit. (See http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html )

而且,当它被定义时,它并不总是代表“真”极限。(参见http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html)

The readlink's manpage also give a way to do that on symlink :

readlink的manpage也给出了一个在symlink上做这个的方法:

Using a statically sized buffer might not provide enough room for the symbolic link contents. The required size for the buffer can be obtained from the stat.st_size value returned by a call to lstat(2) on the link. However, the number of bytes written by readlink() and read‐ linkat() should be checked to make sure that the size of the symbolic link did not increase between the calls.

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

However in the case of /proc/self/exe/ as for most of /proc files, stat.st_size would be 0. The only remaining solution I see is to resize buffer while it doesn't fit.

然而,对于大多数/proc文件来说,state .st_size将是0。我看到的唯一的解决方案是在缓冲区不适合时调整缓冲区的大小。

I suggest the use of vector<char> as follow for this purpose:

为此,我建议使用向量 :

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 "";
}