程序人生 | UNIX环境高级编程技巧之 du 指令实现

本文首发于 2014-07-10 10:00:41

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <stdio.h>
#include <stdlib.h>
#include <glob.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define PATHSIZE 1024

static int path_noloop(const char *path)
{
char *pos;

pos = strrchr(path,'/');//定位最右边的'/'的位置

if(strcmp(pos+1,".") == 0 || (strcmp(pos+1,"..") == 0))
return 0;
return 1;

}

static int64_t mydu(const char *path)
{
int i;
glob_t globres;
int64_t sum;
static struct stat statres;
static char nextpath[PATHSIZE];

if(lstat(path, &statres) < 0)
{
perror("lstat()");
return 0;//exit(1);
}

if(!S_ISDIR(statres.st_mode))
return statres.st_blocks;

strncpy(nextpath, path,PATHSIZE);
strncat(nextpath, "/*" , PATHSIZE);
glob(nextpath,GLOB_NOSORT, NULL, &globres);

strncpy(nextpath, path,PATHSIZE);
strncat(nextpath, "/.*" , PATHSIZE);
glob(nextpath,GLOB_NOSORT|GLOB_APPEND, NULL, &globres);

sum = statres.st_blocks;

for(i = 0 ;i < globres.gl_pathc ; i++)
{
if(path_noloop(globres.gl_pathv[i]))
sum += mydu(globres.gl_pathv[i]);
}

return sum;
}

int main(int argc,char **argv)
{
if(argc < 2)
{
fprintf(stderr,"Usage...\n");
exit(1);
}
printf("%lld 512B blocks\n", (long long int)mydu(argv[1]));
return 0;
}

编译

1
$ gcc -g -Wall testdu.c -o testdu

运行

  • testdf执行效果:
1
2
$ ./testdu /usr/bin
1766184 512B blocks
  • 原生df执行效果:
1
2
$ du -sh /usr/bin
859M /usr/bin

欢迎关注我的微信公众号【数据库内核】:分享主流开源数据库和存储引擎相关技术。

欢迎关注公众号数据库内核
标题 网址
GitHub https://dbkernel.github.io
知乎 https://www.zhihu.com/people/dbkernel/posts
思否(SegmentFault) https://segmentfault.com/u/dbkernel
掘金 https://juejin.im/user/5e9d3ed251882538083fed1f/posts
CSDN https://blog.csdn.net/dbkernel
博客园(cnblogs) https://www.cnblogs.com/dbkernel
文章目录
  1. 1. 代码
  2. 2. 编译
  3. 3. 运行
|