如何实现 readlink 来查找路径
- 2024-11-14 08:29:00
- admin 原创
- 17
问题描述:
使用 readlink 函数作为如何在 C 中找到可执行文件位置的解决方案?,我如何将路径放入 char 数组中?此外,变量 buf 和 bufsize 代表什么以及如何初始化它们?
编辑:我正在尝试获取当前正在运行的程序的路径,就像上面链接的问题一样。该问题的答案说使用readlink("proc/self/exe")
。我不知道如何在我的程序中实现它。我试过:
char buf[1024];
string var = readlink("/proc/self/exe", buf, bufsize);
这显然是不正确的。
解决方案 1:
正确使用 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] = ' ';
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] = ' ';
return std::string(buff);
}
/* handle error condition */
}
使用方法:
int main()
{
std::string selfpath = get_selfpath();
std::cout << selfpath << std::endl;
return 0;
}
解决方案 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] = ' ';
return (std::string(&(buf[0])));
}
/* handle error */
return "";
}
解决方案 3:
让我们看看手册页上是怎么说的:
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;
}
解决方案 4:
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
解决方案 5:
#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
", e ? e : "unknown");
free(e);
return 0;
}
这使用了传统的“当您不知道正确的缓冲区大小时,重新分配增加的 2 的幂”技巧。我们假设为路径名分配少于 64 个字节是不值得的。我们还假设长达 16384(2**14)字节的可执行路径名必须指示程序安装方式的某种异常,并且知道路径名是没有用的,因为我们很快就会遇到更大的问题需要担心。
无需担心像 这样的常量PATH_MAX
。保留这么多内存对于几乎所有路径名来说都是过度的,并且如另一个答案中所述,无论如何都不能保证它是实际的上限。对于此应用程序,我们可以选择一个常识性的上限,例如 16384。即使对于没有常识性上限的应用程序,重新分配增加的 2 的幂也是一个好方法。您只需要log n
调用-byte 结果,并且您浪费的内存容量与结果的长度成正比。它还可以避免在和 之间n
字符串长度发生变化的竞争条件。realloc()
`readlink()`
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件