我目前正在执行一项任务,我需要在不使用pwd
或getcwd
的情况下实现getenv
的功能。然而,我陷入无限循环,因为当我使用chdir("..")
时,它似乎在我到达根目录后将我回到同一目录。我发现了一个similar question,但它是使用perl模块解决的,所以没有帮助。
我的第一个想法是跟踪以前的目录名称并将其与当前目录名称进行比较以查看它们是否匹配,但我无法看到任何方法,因为我没有目录名称的大小,d_name
中每个文件或目录的名称之间都有空字符。
到目前为止,这是我的代码(注意它可能还有其他错误,但我需要先解决这个问题):
#include <stdio.h>
#include <dirent.h>
#include <linux/limits.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
void get_path(char *path, int path_len);
int main(void)
{
int path_len = -1;
char path[PATH_MAX];
/* get and print the path */
get_path(path, path_len);
path[0] = '\0';
printf("%s\n", path);
return 0;
}
/* get the path from the current directory to the root */
void get_path(char *path, int path_len)
{
struct dirent *dirp;
DIR *dp;
/* open current dir */
if ((dp = opendir(".")) == NULL)
{
perror("mypwd");
exit(1);
}
/* go through this dir */
while ((dirp = readdir(dp)) != NULL)
{
/* found its parent */
if (strcmp(dirp->d_name, "..") == 0)
{
/* on to a new path */
path_len++;
if (path_len > PATH_MAX)
{
fprintf(stderr, "path too long\n");
exit(1);
}
/* go to parent and continue */
chdir("..");
get_path(path, path_len);
/* add this name to our path */
strcat(path, dirp->d_name);
}
}
closedir(dp);
}
如何判断我是否已到达文件根目录?
答案 0 :(得分:1)
根目录的父目录的inode编号是2,与根目录本身的inode编号相同(并且设备编号相同)。至少,在经典的Unix文件系统中也是如此 - 以及一些现代的(可能都是它们)。
在我的Mac上,我可以运行:
$ ls -lid /. /..
2 drwxr-xr-x 34 root wheel 1088 Apr 25 07:55 /.
2 drwxr-xr-x 34 root wheel 1088 Apr 25 07:55 /..
$
请注意,(已安装的)文件系统的根目录在磁盘上也具有inode编号2,但是当您stat()
挂载的文件系统的根目录时,您将获得不同的inode和设备编号。父目录。
例如,再次在Mac上安装了/private/var/vm/
:
$ ls -lid /private/var /private/var/vm /private/var/vm/. /private/var/vm/..
13212009 drwxr-xr-x 26 root wheel 832 Sep 26 2017 /private/var
2 drwxr-xr-x 6 root wheel 192 May 5 12:44 /private/var/vm
2 drwxr-xr-x 6 root wheel 192 May 5 12:44 /private/var/vm/.
13212009 drwxr-xr-x 26 root wheel 832 Sep 26 2017 /private/var/vm/..
$
使用自定义fstat
程序,您可以看到设备编号发生变化:
$ fstat /private/var /private/var/vm /private/var/vm/. /private/var/vm/.. / /. /..
Mode Inode Links UID GID Size Modtime Dev RDev File
0040755 13212009 26 0 0 832 1506482024 16777223 0 /private/var
0040755 2 6 0 0 192 1525549483 16777221 0 /private/var/vm
0040755 2 6 0 0 192 1525549483 16777221 0 /private/var/vm/.
0040755 13212009 26 0 0 832 1506482024 16777223 0 /private/var/vm/..
0040755 2 34 0 0 1088 1524668138 16777223 0 /
0040755 2 34 0 0 1088 1524668138 16777223 0 /.
0040755 2 34 0 0 1088 1524668138 16777223 0 /..
$
GNU stat
和BSD stat
命令产生相同的设备编号信息,但它们的输出更冗长和/或更不可读。