我现在正在做一个任务,我需要在不使用pwdgetcwd的情况下实现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);
}

我怎么知道我已经到达了文件根目录?

最佳答案

根目录的父目录的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 /..
$

GNUstat和BSDstat命令生成相同的设备号信息,但它们的输出更详细和/或更不可读。

关于c - 如何确定当前目录是否是C中的根目录?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50205605/

10-12 07:36
查看更多