我正在使用getcwd函数来检索应用程序的当前工作目录。 在某些情况下,它失败了,错误是ENOENT。我从不同的线程调用getcwd,但是连续地,有时我面对ENOENT,但我不知道为什么。 上面的链接表示ENOENT表示“当前工作目录已取消链接”。但目录存在。
以下是我使用的功能片段:
更新:根据@Aganju和@molbdnilo的建议更新代码:
std::string get_working_dir()
{
char buf[PATH_MAX];
memset(buf, 0, sizeof(buf));
char * result = getcwd(buf, sizeof(buf));
std::string working_path = buf;
// Check for possible errors.
if (result == NULL)
{
switch (errno)
{
case EACCES:
break;
case EFAULT:
break;
case EINVAL:
break;
case ENAMETOOLONG:
break;
case ENOENT:
{
if (working_path.empty())
{
const char* pwd = getenv("PWD");
working_path = (pwd) ? pwd : "";
}
break;
}
case ERANGE:
break;
default:
break;
}
return working_path;
}
}
如果我面对ENOENT,我会检索“PWD”环境变量,因为我在CentOS 5.11和Ubuntu 16.04上工作,当CentOS上的getcwd失败时,它返回一个空缓冲区。
更新:
我注意到来自主线程的调用没有失败,但是当我从另一个线程调用该函数时它失败并且errno是ENOENT。
答案 0 :(得分:2)
如molbdnilo所述,您需要先检查返回值。
您链接到州的手册:
[...]失败时,这些函数返回NULL,并且errno设置为 表示错误。[...]
换句话说,如果没有失败,errno
不设置,并且包含之前发生的任何调用所包含的内容,可能很长之前的时间,在这种情况下没有意义。
使用char * result = getcwd(buf, sizeof(buf));
之类的内容,然后检查if (result == NULL) { switch (errno) ...
等
答案 1 :(得分:1)
这可能发生在以下情况中,我们可以使用shell脚本语法通过多进程序列图来说明:
process A process B
$ cd ~ $ cd ~
user $ mkdir foo
user $ cd foo
user $ rm -rf foo
user/foo $ pwd
/home/user/foo
user/foo $ cd .
cd: error retrieving current
directory: getcwd: cannot access
parent directories: No such file or directory
类Unix操作系统中的每个进程都有一个当前工作目录,它保存对文件系统中对象的引用。在进程删除当前目录之前,该对象不能被回收为可用空间。
上面,流程A继续保留曾经 ~/foo
的目录。目录结构中不再存在路径,但目录对象仍然存在。
getcwd
系统调用意识到这一点:它看到调用进程的当前工作目录没有链接到目录结构,因此没有路径,因此报告错误。
pwd
shell命令有效,因为它只是在不调用getcwd
的情况下反弹shell知道的一段数据;但是当我们尝试cd .
时,会发生错误(在GNU / Linux系统上使用Bash重现;结果可能会有所不同)。