程序人生 | 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; }
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
|
运行
1 2
| $ ./testdu /usr/bin 1766184 512B blocks
|
1 2
| $ du -sh /usr/bin 859M /usr/bin
|
欢迎关注我的微信公众号【数据库内核】:分享主流开源数据库和存储引擎相关技术。