如何实现 readlink 来查找路径

2024-11-14 08:29:00
admin
原创
17
摘要:问题描述:使用 readlink 函数作为如何在 C 中找到可执行文件位置的解决方案?,我如何将路径放入 char 数组中?此外,变量 buf 和 bufsize 代表什么以及如何初始化它们? 编辑:我正在尝试获取当前正在运行的程序的路径,就像上面链接的问题一样。该问题的答案说使用readlink("...

问题描述:

使用 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()`

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用