如何判断当前目录是否是C中的根目录?

时间:2018-05-07 00:06:23

标签: c directory

我目前正在执行一项任务,我需要在不使用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);
}

如何判断我是否已到达文件根目录?

1 个答案:

答案 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命令产生相同的设备编号信息,但它们的输出更冗长和/或更不可读。