问题引入

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

思路分析

熟悉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>
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 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>
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 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 }
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慢慢进行熟悉。

Linux程序开发中如何判断目录是否为根目录?的更多相关文章

  1. IOS开发中如何判断程序第一次启动(根据判断结果决定是否显示新手操作引导)

    IOS开发中如何判断程序第一次启动 在软件下载安装完成后,第一次启动往往需要显示一个新手操作引导,来告诉用户怎么操作这个app,这就需要在程序一开始运行就判断程序是否第一次启动,如果是,则显示新手操作 ...

  2. 在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)

    本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...

  3. 微信小程序开发教程 #043 - 在小程序开发中使用 npm

    本文介绍了如何在微信小程序开发中使用 npm 中包的功能,大大提高微信小程序的开发效率,同时也是微信小程序系列教程的视频版更新. 微信小程序在发布之初没有对 npm 的支持功能,这也是目前很多前端开发 ...

  4. 总结微信小程序开发中遇到的坑

    总结微信小程序开发中遇到的坑,一些坑你得一个一个的跳啊,/(ㄒoㄒ)/~~ 1,页面跳转和参数传递实例 首先说一下我遇到的需求有一个我的消息页面,里面的数据都是后端返回的,返回的数据大致如下,有一个是 ...

  5. IOS程序开发中-跳转到 发送短信界面 实现发短信

    前言:我发现我标题取的不好,谁帮我取个承接上下文的标题?评论一下,我改 项目需求:在程序开发中,我们需要在某个程序里面发送一些短信验证(不是接收短信验证,关于短信验证,传送门:http://www.c ...

  6. AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题

    AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子. 一 AOP的基本概念 (1)Asp ...

  7. Delphi 10.2 Linux 程序开发环境部署的基本步骤(网络连接方式要选择桥接或者是Host Only)

    Delphi 10.2 Linux 程序开发环境部署的基本步骤 http://blog.qdac.cc/?p=4477 升級到 Delphi 10.2 Tokyo 笔记http://www.cnblo ...

  8. 解决微信小程序开发中wxss中不能用本地图片

    微信小程序开发中wxss中不能用本地图片,我们可以用将我们的图片传到服务器上,然后直接引用在线地址.但是当我们没有服务器时,我们可以用"图床",这个具体可以百度.这里我们用第二种方 ...

  9. 程序开发中的术语,如IDE,OOP等等

    我们在开发程序过程中,会用到一些与编译有关的术语,比如:[编辑器.编译器.调试器.连接器,链接器.解释器,集成开发环境(Integrated Development Environment,IDE). ...

随机推荐

  1. 每个人都可以用C语言写的推箱子小游戏!今天你就可以写出属于自己项目~

    C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...

  2. 如果你想or即将成为一名程序员,那你需要知道这些东西!上岗须知~

    前两天公司学院的同学给我看了一下即将入职的应届生的数量,真是不少.感慨一下,一批新人即将到来,而自己又老去了一岁.码农是一个必将终身学习的职业.而相关的知识越来越多了.接下来该学什么?接下来该干什么? ...

  3. Linux关机时执行指定脚本

    要实现在Linux关机时执行某个脚本的具体思路 1.在文件夹 /etc/init.d/ 下创建关机时需要执行的脚本 file_name; 2.分别在文件夹 /etc/rc0.d/ 和 /etc/rc6 ...

  4. java内存模型深入理解

    作为一个java程序员 jvm 虚拟机应该是最先接触的了,但是当初由于理解能力有限一直没搞明白是怎么回事,而是将他理解为运行java程序的环境,不过这也没错.但是随着工作时间的增加开始思考jvm里面工 ...

  5. Messenger实现进程间通信(IPC)

    messenger内部也是实现aidl通信,所以可以看做一个轻量级aidl,但相对比较简单.首先开启一个服务并实现一个Handler用来处理消息,在onbind方法中返回IBinder对象,通过Ser ...

  6. Linux的top命令及交换分区

    TOP命令关键指标 %MEM,在内存中的占用率 %CPU,使用率,如果两核,最大可到200% TIME+, 占用cpu的总时间/s SHR,分享内存 RES, 常驻内存,进程当前使用的内存大小,不包括 ...

  7. 正则表达式小应用之对xml格式字符串每个字段加双引号

    通过Python对接口进行自动化后需要把xml格式的报文放到LoadRunner上进行压力测试,在pyCharm控制台打印出报文后,把报文放到LoadRunner中做了格式调整后,每个字段需要添加双引 ...

  8. 4G工业路由器的传输功率是越高越好吗?

    现在人们越来越多的利用运营商网络进行家庭的Wi-Fi上网,早已是非常普遍的事情了.而无线路由器作为设备组网的重要组成部分,与路由器相关的话题.知识总会能够引发大家的热议.这里,以众山物联网研发.生产的 ...

  9. 推荐给 Java 程序员的 7 本书

    < Java 编程思想> 适合各个阶段 Java 程序员的必备读物.书中对 Java 进行了详尽的介绍,与其它语言做了对比,解释了 Java 很多特性出现的原因和解决的问题.初学者可以通过 ...

  10. IDEA通过file-open打开以前的项目无法运行

    在学习java的过程中我们会建立很多项目,IDEA默认打开最近一次编辑的项目,当我们打开以前的项目时会发现run图标变成灰色了, 解决办法: 1. 手动设置src为根目录 选中src目录--右键--m ...