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

代码

#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;
}

编译

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

运行

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

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

欢迎关注公众号数据库内核

标题网址
GitHubhttps://dbkernel.github.io
知乎https://www.zhihu.com/people/...
思否(SegmentFault)https://segmentfault.com/u/db...
掘金https://juejin.im/user/5e9d3e...
CSDNhttps://blog.csdn.net/dbkernel
博客园(cnblogs)https://www.cnblogs.com/dbkernel

dbkernel
33 声望7 粉丝

目前从事云数据库MySQL数据库内核研发工作,曾做过Postgres-XC、Greenplum等分布式数据库的内核开发。热衷于研究主流数据库架构、源码,对关系型数据库 MySQL/PostgreSQL及分布式数据库有深入研究。