readlink将errno设置为ENOENT

时间:2017-01-14 02:40:40

标签: c++ linux readlink

我是一名经验不足的Linux程序员,我正在尝试学习使用基于此question and answerreadlink()

我对readlink()的调用返回-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] = '\0';
  }

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

我尝试过的事情:

  • 编译后:sudo ./a.out(认为由于缺少权限而限制了目录访问)。结果:./a.out
  • 的行为不变
  • 执行期间SIGINT程序,并验证/proc/<pid>/exe是否存在。结果:每次运行程序时都会一直存在。
  • 确认目标链接的值在499个字符之内。

有人可以帮助确定问题吗?阅读了readlink手册页和在线说明以及着名的StackOverflow文章后,我仍然不清楚是什么问题。

谢谢。

2 个答案:

答案 0 :(得分:3)

proc/1234/exe是相对路径。

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

其次,因为readlink()将在缓冲区太小的情况下截断结果,所以您应该考虑返回值为== bufsiz的情况,因为可能发生了截断。你无法知道。

此外,“执行文件夹”不是/proc/<pid>/exe给你的。 /proc/<pid>/exe是当前运行的可执行文件(文件)的符号链接,而不是目录。

答案 1 :(得分:1)

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)。