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

问题引入判断某个目录字符串是否是根目录,咋一听很简单,只要判断字符串是否是"/"即可,但是,很多情况下使用的路径是相对路径,那么如何判断相对路径是根目录呢?熟悉Linux的同学应该知道,每个目录下都有.和..两个目录,分别指代当前目录和父

问题引入

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

思路分析

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

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

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

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

再来看一下dirent的结构

1 structdirent {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

2 #include

3 #include

4 #include

5

6 bool isRoot(const char*path)7 {8 if (strcmp(path, "/") == 0)9 return true;10

11 char dp[256] = {0};12 int l =strlen(path);13 memcpy(dp, path, l);14

15 if (dp[l - 1] != "/")16 {17 dp[l] = "/";18 l += 1;19 }20

21 DIR* d =opendir(dp);22 if (!d)23 {24 printf("failed to open dir\n");25 return false;26 }27

28 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 }39

40 if (dino > 0 && ddino > 0)41 break;42 }43 return dino == ddino && dino != 0;44 }45

46 int main(int argc, char*argv[])47 {48 if (argc != 2)49 {50 printf("usage : app path\n");51 return 0;52 }53

54 if (isRoot(argv[1]))55 printf("this path is root\n");56 else

57 printf("this path is not root\n");58 return 0;59 }

编译

g++ -o root root.cpp

下面来验证一下

# ./root /

this path isroot

# ./root ./

this path isnot root

# ./root ./../

this path isnot root

# ./root ./../../

this path isnot root

# ./root ./../../../

this path isnot root

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

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

. 2..1

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

int stat(const char *, struct stat *)

修改代码后如下:

1 #include

2 #include

3 #include

4 #include

5 #include

6

7 bool isRoot(const char*path)8 {9 if (strcmp(path, "/") == 0)10 return true;11

12 char dp[256] = {0};13 int l =strlen(path);14 memcpy(dp, path, l);15

16 if (dp[l - 1] != "/")17 {18 dp[l] = "/";19 l += 1;20 }21

22 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 structstat 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 structstat s;48 stat(sp, &s);49 //printf("dot %s %lld\n", ent->d_name, s.st_ino);

50 dino =s.st_ino;51 }52

53 if (dino > 0 && ddino > 0)54 break;55 }56 return dino == ddino && dino != 0;57 }58

59 int main(int argc, char*argv[])60 {61 if (argc != 2)62 {63 printf("usage : app path\n");64 return 0;65 }66

67 if (isRoot(argv[1]))68 printf("this path is root\n");69 else

70 printf("this path is not root\n");71 return 0;72 }73

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

总结

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

以上信息来源于网络,如有侵权,请联系站长删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值