ls隠しファイルを表示する
ls -a。:current
directoryで始まる、隠しファイルを含むすべてのファイルを表示します
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$
現在のディレクトリをグロブできません。親ディレクトリ...はスタックを壊します
。
実験:彼らの単純な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コマンドは、後でディレクトリストリームを使用して実装されます。