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 ""
我尝试过的东西:
- 编译后:
sudo ./a.out
(以为是权限不足导致目录访问受限)。结果:./a.out
的行为不变
- 在执行期间对程序发出信号,并验证
/proc/<pid>/exe
存在。结果:它始终存在于程序的每个 运行 中。
- 已验证目标 link 的值在 499 个字符以内。
谁能帮忙找出问题所在?阅读了 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
是指向当前 运行 可执行文件(文件)的符号链接,而不是目录。
我是一个没有经验的 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 ""
我尝试过的东西:
- 编译后:
sudo ./a.out
(以为是权限不足导致目录访问受限)。结果:./a.out
的行为不变
- 在执行期间对程序发出信号,并验证
/proc/<pid>/exe
存在。结果:它始终存在于程序的每个 运行 中。 - 已验证目标 link 的值在 499 个字符以内。
谁能帮忙找出问题所在?阅读了 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
是指向当前 运行 可执行文件(文件)的符号链接,而不是目录。