AI智能
改变未来

Linux程序开发中如何判断目录是否为根目录?


问题引入

判断某个目录字符串是否是根目录,咋一听很简单,只要判断字符串是否是\”/\”即可,但是,很多情况下使用的路径是相对路径,那么如何判断相对路径是根目录呢?

思路分析

熟悉Linux的同学应该知道,每个目录下都有.和..两个目录,分别指代当前目录和父目录,考虑从这个点下手,根目录的当前目录和父目录指向相同,也就是说这两个文件的描述符是一样的。

大体思路有了之后,来看下Linux中常用的目录操作的函数:

1 DIR *opendir(const char *)2 struct dirent *readdir(DIR *)3 int closedir(DIR *)

它们位于dirent.h头文件中。

再来看一下dirent的结构

1 struct dirent {2     ino_t d_ino;            /* file number of entry */3     __uint16_t d_reclen;        /* length of this record */4     __uint8_t  d_type;      /* file type, see below */5     __uint8_t  d_namlen;        /* length of string in d_name */6     char d_name[__DARWIN_MAXNAMLEN + 1];    /* name must be no longer than this */7 };

解决方案

开始动手编码,如下:

1 #include <stdio.h>2 #include <stdlib.h>3 #include <string.h>4 #include <dirent.h>56 bool isRoot(const char* path)7 {8     if (strcmp(path, \"/\") == 0)9         return true;1011     char dp[256] = {0};12     int l = strlen(path);13     memcpy(dp, path, l);1415     if (dp[l - 1] != \'/\')16     {17         dp[l] = \'/\';18         l += 1;19     }2021     DIR* d = opendir(dp);22     if (!d)23     {24         printf(\"failed to open dir\\n\");25         return false;26     }2728     uint64_t dino = 0, ddino = 0;29     while (dirent* ent = readdir(d))30     {31         if (strcmp(ent->d_name, \"..\") == 0)32         {33             ddino = ent->d_ino;34         }35         if (strcmp(ent->d_name, \".\") == 0)36         {37             dino = ent->d_ino;38         }3940         if (dino > 0 && ddino > 0)41             break;42     }43     return dino == ddino && dino != 0;44 }4546 int main(int argc, char* argv[])47 {48     if (argc != 2)49     {50         printf(\"usage : app path\\n\");51         return 0;52     }5354     if (isRoot(argv[1]))55         printf(\"this path is root\\n\");56     else57         printf(\"this path is not root\\n\");58     return 0;59 }

编译

g++ -o root root.cpp

下面来验证一下

# ./root /this path is root# ./root ./this path is not root# ./root ./../this path is not root# ./root ./../../this path is not root# ./root ./../../../this path is not root# ./root ./../../../.. #注意,我的机器上这里其实已经是根目录了this path is not root

奇怪的问题发生了,本应该通过的内容竟然不是根目录。进入代码,打印一下isRoot函数中.和..目录的name和ino。

. 2.. 1

难道是假设错误?如果想要取得inode可以通过stat函数,那么我们该用stat函数试一下

int stat(const char *, struct stat *)

修改代码后如下:

1 #include <stdio.h>2 #include <stdlib.h>3 #include <string.h>4 #include <dirent.h>5 #include <sys/stat.h>67 bool isRoot(const char* path)8 {9     if (strcmp(path, \"/\") == 0)10         return true;1112     char dp[256] = {0};13     int l = strlen(path);14     memcpy(dp, path, l);1516     if (dp[l - 1] != \'/\')17     {18         dp[l] = \'/\';19         l += 1;20     }2122     DIR* d = opendir(dp);23     if (!d)24     {25         printf(\"failed to open dir\\n\");26         return false;27     }28     uint64_t dino = 0, ddino = 0;29     while (dirent* ent = readdir(d))30     {31         if (strcmp(ent->d_name, \"..\") == 0)32         {33             char pp[256] = {0};34             memcpy(pp, dp, l);35             pp[l] = \'.\';36             pp[l + 1] = \'.\';37             struct stat s;38             stat(pp, &s);39             //printf(\"ddot %s %lld\\n\", ent->d_name, s.st_ino);40             ddino = s.st_ino;41         }42         if (strcmp(ent->d_name, \".\") == 0)43         {44             char sp[256] = {0};45             memcpy(sp, dp, l);46             sp[l] = \'.\';47             struct stat s;48             stat(sp, &s);49             //printf(\"dot %s %lld\\n\", ent->d_name, s.st_ino);50             dino = s.st_ino;51         }5253         if (dino > 0 && ddino > 0)54             break;55     }56     return dino == ddino && dino != 0;57 }5859 int main(int argc, char* argv[])60 {61     if (argc != 2)62     {63         printf(\"usage : app path\\n\");64         return 0;65     }6667     if (isRoot(argv[1]))68         printf(\"this path is root\\n\");69     else70         printf(\"this path is not root\\n\");71     return 0;72 }73

再次编译验证,发现这次的结果是正确的。经过查证后发现,在使用readdir时取得的dirent中的iNode不一定是正确的,还需要从stat中取。

总结

到此就完成了目录是否为根目录的判断,需要对Linux的API慢慢进行熟悉。

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Linux程序开发中如何判断目录是否为根目录?