ls 查看 非隐藏文件
ls -a 查看所有文件,包括隐藏的文件,以 . 开头的
. :当前目录
mhr@ubuntu:~/work/linux/muluheyonghucaozuo/26$ ls
mydu.c
mhr@ubuntu:~/work/linux/muluheyonghucaozuo/26$
mhr@ubuntu:~/work/linux/muluheyonghucaozuo/26$ ls -a
. .. mydu.c
mhr@ubuntu:~/work/linux/muluheyonghucaozuo/26$
不能 glob 当前目录 . 和上级目录 … 会导致栈破裂
.
实验: 实现自己的简单的 du 命令
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <glob.h>
#include <string.h>
#define PATHSIZE 1024
static int path_noloop(const char *path)
{
char *pos;
//定位最右边的'/'的位置
pos = strrchr(path,'/');
if(pos == NULL)
exit(1);
//判断 当前文件是 "." 和 ".." ,这两种情况不操作 直接越过,不然会导致栈破裂
if(strcmp(pos+1,".")==0 || (strcmp(pos+1,"..")==0))
return 0;
return 1;
}
//防止大小溢出 long long int
static int64_t mydu(const char *path)
{
struct stat statres;
char nextpath[PATHSIZE];
glob_t globres;
int i;
int64_t sum=0;
//不使用 stat 遇到链接文件的时候 会返回 实际链接文件的属性信息,而我们此时需要返回链接文件本身属性信息
if(lstat(path,&statres) < 0)
{
perror("lstat");
exit(1);
}
//如果是非目录文件,直接返回文件大小 k: 块数/2
if(!S_ISDIR(statres.st_mode))
return statres.st_blocks;
// nextpath/*
//strcpy(nextpath,path);
strncpy(nextpath,path,PATHSIZE);
strncat(nextpath,"/*",PATHSIZE);
glob(nextpath,0, NULL, &globres);
// nextpath/.*
//strcpy(nextpath,path);
strncpy(nextpath,path,PATHSIZE);
strncat(nextpath,"/.*",PATHSIZE);
glob(nextpath,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]);
}
globfree(&globres);
return sum;
}
int main(int argc,char* argv[])
{
if(argc < 2)
{
fprintf(stderr,"Usage:%s <src_file> <dest_file>\n",argv[0]);
exit(1);
}
printf("%lld\n",mydu(argv[1])/2);
exit(0);
}
mhr@ubuntu:~/work/linux/muluheyonghucaozuo/26$ gcc mydu.c
mydu.c: In function ‘main’:
mydu.c:75:9: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘int64_t {aka long int}’ [-Wformat=]
printf("%lld\n",mydu(argv[1])/2);
^
mhr@ubuntu:~/work/linux/muluheyonghucaozuo/26$ ./a.out /etc/
13480
mhr@ubuntu:~/work/linux/muluheyonghucaozuo/26$ du /etc/
...
13480 /etc/
异常:
int glob() 成功返回0,我在测试代码的时候 发现 如果我对 glob()的结果进行校验,发现不能正常计算出目标文件的大小,经测试 发现 glob()函数有返回3的情形:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <glob.h>
#include <string.h>
#define PATHSIZE 1024
static int path_noloop(const char *path)
{
char *pos;
pos = strrchr(path,'/');
if(pos == NULL)
exit(1);
if(strcmp(pos+1,".")==0 || (strcmp(pos+1,"..")==0))
return 0;
return 1;
}
static int64_t mydu(const char *path)
{
struct stat statres;
char nextpath[PATHSIZE];
glob_t globres;
int i,err=0;
int64_t sum=0;
if(lstat(path,&statres) < 0)
{
perror("lstat");
exit(1);
}
if(!S_ISDIR(statres.st_mode))
return statres.st_blocks;
// nextpath/*
//strcpy(nextpath,path);
strncpy(nextpath,path,PATHSIZE);
strncat(nextpath,"/*",PATHSIZE);
glob(nextpath,0, NULL, &globres);
// nextpath/.*
//strcpy(nextpath,path);
strncpy(nextpath,path,PATHSIZE);
strncat(nextpath,"/.*",PATHSIZE);
err = glob(nextpath,GLOB_APPEND,NULL,&globres);
printf("err = %d\n",err);
if(err)
{
fprintf(stderr,"glob():%s\n",strerror(err));
exit(1);
}
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:%s <src_file> <dest_file>\n",argv[0]);
exit(1);
}
printf("%lld\n",mydu(argv[1])/2);
exit(0);
}
...
err = 0
err = 0
err = 0
err = 0
err = 0
err = 3
glob():No such process
mhr@ubuntu:~/work/linux/muluheyonghucaozuo/26$
所以暂时没有加 glob 的返回值判断。
后面补充用 目录流 实现du命令。