如何实现readlink查找路径
Posted
技术标签:
【中文标题】如何实现readlink查找路径【英文标题】:How to implement readlink to find the path 【发布时间】:2011-07-28 09:28:35 【问题描述】:使用 readlink 函数作为How do I find the location of the executable in C? 的解决方案,我如何将路径放入 char 数组?另外,变量 buf 和 bufsize 代表什么以及如何初始化它们?
编辑:我正在尝试获取当前正在运行的程序的路径,就像上面链接的问题一样。该问题的答案说使用readlink("proc/self/exe")
。我不知道如何在我的程序中实现它。我试过了:
char buf[1024];
string var = readlink("/proc/self/exe", buf, bufsize);
这显然是不正确的。
【问题讨论】:
【参考方案1】:#include <stdlib.h>
#include <unistd.h>
static char *exename(void)
char *buf;
char *newbuf;
size_t cap;
ssize_t len;
buf = NULL;
for (cap = 64; cap <= 16384; cap *= 2)
newbuf = realloc(buf, cap);
if (newbuf == NULL)
break;
buf = newbuf;
len = readlink("/proc/self/exe", buf, cap);
if (len < 0)
break;
if ((size_t)len < cap)
buf[len] = 0;
return buf;
free(buf);
return NULL;
#include <stdio.h>
int main(void)
char *e = exename();
printf("%s\n", e ? e : "unknown");
free(e);
return 0;
这使用了传统的“当您不知道正确的缓冲区大小时,重新分配二的递增幂”技巧。我们假设为路径名分配少于 64 个字节的努力是不值得的。我们还假设长达 16384 (2**14) 字节的可执行路径名必须表明程序安装方式存在某种异常,并且知道路径名没有用,因为我们很快就会遇到更大的问题需要担心关于。
无需为PATH_MAX
之类的常量而烦恼。对于几乎所有路径名来说,保留这么多内存都是多余的,正如另一个答案中所指出的那样,无论如何都不能保证它是实际的上限。对于这个应用程序,我们可以选择一个常识性上限,例如 16384。即使对于没有常识性上限的应用程序,重新分配 2 的递增幂也是一个好方法。您只需要log n
调用n
-byte 结果,您浪费的内存容量与结果的长度成正比。它还避免了字符串长度在realloc()
和readlink()
之间变化的竞争条件。
【讨论】:
【参考方案2】:接受的答案几乎是正确的,但您不能依赖 PATH_MAX,因为它是
如果系统没有这样的定义,则不保证按 POSIX 定义 限制。
(来自 readlink(2) 手册页)
此外,当它被定义时,它并不总是代表“真实”的限制。 (见http://insanecoding.blogspot.fr/2007/11/pathmax-simply-isnt.html)
readlink 的联机帮助页也提供了一种在符号链接上执行此操作的方法:
使用静态大小的缓冲区可能无法为 符号链接内容。缓冲区所需的大小可以是 从调用 lstat(2) 返回的 stat.st_size 值获得 链接。但是,readlink() 和 read- 写入的字节数 应检查 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 "";
【讨论】:
总是加 100 有什么原因吗(而不是像len - buf.size()
这样的东西?)【参考方案3】:
此Use the readlink() function properly 用于正确使用readlink
函数。
如果您的路径位于 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 */
如果你只追求固定路径:
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 */
使用它:
int main()
std::string selfpath = get_selfpath();
std::cout << selfpath << std::endl;
return 0;
【讨论】:
不,抱歉,我想我的句子措辞不正确。我没有路径,我正在使用 readlink("/proc/self/exe", buf, bufsize);正确地检索它。 我不明白你在说什么。请编辑您的问题以显示您所拥有的内容,以及您想要的示例。 好的,我输入了更多细节,但我的原始答案在固定路径下效果很好...... 只是添加一些我一直在努力的细节:get_selfPath()
函数返回包含可执行文件名称的路径。要获取删除 exe 名称的路径,您可以执行以下操作:std::string::size_type t = path.find_last_of("/")
,然后是 path = path.substr(0,t)
。我不知道为什么这在任何地方都没有得到足够的澄清;)
@a.lasram:这根本不是错字。【参考方案4】:
让我们看看the 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.
好的。应该足够简单。给定 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;
【讨论】:
不应该是... if (readlink("/proc/self/exe", buf, sizeof(buf)-1)if (readlink(/*...*/))
测试非零值。小于 0 是非零。
readlink 在成功时返回 >0。 “成功时,readlink() 返回放在 buf 中的字节数。出错时,返回 -1”。 linux.die.net/man/2/readlink.
好的。届时将进行编辑。这对于系统调用来说有点不寻常。通常 0 表示成功。【参考方案5】:
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;
取自:http://www.delorie.com/gnu/docs/glibc/libc_279.html
【讨论】:
以上是关于如何实现readlink查找路径的主要内容,如果未能解决你的问题,请参考以下文章