readlink 将 errno 设置为 ENOENT

readlink sets errno to ENOENT

我是一个没有经验的 Linux 程序员,我正在尝试基于此 question and answer.

学习使用 readlink()

我调用 readlink() returns -1 并将 errno 设置为 2 (ENOENT)。

代码:

#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <iostream>
#include <algorithm>
#include <cstdio>

int main(int argc, char* argv[])
{
  char szTmp[100];
  snprintf(szTmp, 100, "proc/%d/exe", getpid());
  std::cout << "szTmp is " << szTmp << std::endl;
  char executingFolder[500];
  errno = 0;
  int bytes = std::min(readlink(szTmp, executingFolder, 500), (ssize_t)499);

  if (bytes > 0)
  {
    executingFolder[bytes] = '[=10=]';
  }

  std::cout << "bytes is " << bytes << std::endl;
  std::cout << "errno is " << errno;
  if (ENOENT == errno)
  {
    std::cout << " ENOENT";
  }
  std::cout << std::endl;
  std::cout << "Executing folder is \"" << executingFolder << "\"" << std::endl;

  return 0;
}

输出:

(自 pid 更改以来一次迭代的示例)

szTmp is proc/22272/exe
bytes is -1
errno is 2 ENOENT
Executing folder is ""

我尝试过的东西:

谁能帮忙找出问题所在?阅读了 readlink 手册页和在线描述,以及著名的 Whosebug 文章后,我仍然不清楚哪里出了问题。

谢谢。

proc/22272/exe 是相对路径名。它解析为文件 exe,在目录 22272 中,在目录 proc 中,在您的 当前 目录中。除非您当前的目录是 /,否则它不太可能存在。

您需要一个 绝对 路径名,以 / 开头,在本例中为 /proc/22272/exe.

改变这个:

snprintf(szTmp, 100, "proc/%d/exe", getpid());

对此:

snprintf(szTmp, 100, "/proc/%d/exe", getpid());

但在修复程序之前,您可以试试这个:

( cd / ; ~/a.out )

(假设 a.out 在您的主目录中)。

proc/1234/exe是相对路径。

我想你想要 /proc/%d/exe,这是一个绝对路径,并且正确地引用了 /proc 目录。


其次,因为readlink()会在缓冲区太小的情况下截断结果,所以你应该考虑return值为== bufsiz的情况是错误的,因为截断可能已经发生。你不可能知道。


另外,"Executing folder" 不是 /proc/<pid>/exe 给你的。 /proc/<pid>/exe 是指向当前 运行 可执行文件(文件)的符号链接,而不是目录。