函数原型:
int glob(const char *pattern, int flags,
int errfunc(const char *epath, int eerrno),
glob_t *pglob);
pglob的类型glob_t
typedef struct {
size_t gl_pathc; //匹配到的数量
char **gl_pathv; //匹配到的元素放在这里
size_t gl_offs;
}glob_t;
参数:
pattern 要分析的路径,如/*表示匹配根文件下的所有文件(不包括隐藏文件)
flags flags参数可以设置特殊要求,如无特殊要求置为0
errfunc glob函数执行出错会执行的函数,出错的路径会回填到epath中,
出错的原因回填到eerrno中。如不关注错误可设置为NULL
pglob 解析出来的结果放在这个参数里
返回值:
成功 0
示例
示例1:
使用glob函数打印/etc/ 目录下以a开头.conf结尾的文件。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glob.h>
#include <unistd.h>
#define PAT "/etc/a*.conf"
static int errfunc(const char *errpath,int eerrno)
{
puts(errpath);
fprintf(stderr,"ERROR MSG:%s\n",strerror(eerrno));
return 0;
}
int main()
{
glob_t globres;
int i,err;
err = glob(PAT,0,errfunc,&globres);
if(err)
{
printf("Error code = %d\n",err);
exit(1);
}
//打印解析出来的参数
for(i = 0;i < globres.gl_pathc;i++)
{
puts(globres.gl_pathv[i]);
}
//释放申请的空间
globfree(&globres);
return 0;
}
运行结果如下图:
示例2:
使用glob函数实现du命令,查看文件或目录的大小。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <glob.h>
#define PATHSIZE 1024
static int path_noloop(const char *path)
{
char* pos;
//使用strrchr找到字符串里最右边的一个字符即 / ,成功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 err,i;
int64_t sum;
//使用lstat函数获得文件(目录)属性,lstat函数不会对链接文件展开
if(lstat(path,&statres) < 0)
{
perror("lstat()");
exit(1);
}
//判断获得的属性信息,使用宏判断是否是目录,如果是非目录直接返回大小
if(!S_ISDIR(statres.st_mode))
return statres.st_blocks;
//将path的内容拷贝到nextpath中
strncpy(nextpath,path,PATHSIZE);
//在nextpath中追加/*字符串
strncat(nextpath,"/*",PATHSIZE);
//使用glob函数解析nextpath中非隐藏的文件
err = glob(nextpath,0,NULL,&globres);
if(err)
{
printf("glob error code = %d\n",err);
exit(1);
}
//将path的内容拷贝到nextpath中
strncpy(nextpath,path,PATHSIZE);
//在nextpath中追加/.*字符串
strncat(nextpath,"/.*",PATHSIZE);
//使用glob函数解析nextpath中隐藏的文件,GLOB_APPEND标志意思是将结果追加到 pglob 结构体中
err = glob(nextpath,GLOB_APPEND,NULL,&globres);
if(err)
{
fprintf(stderr,"i ggError code = %s\n",strerror(err));
exit(1);
}
sum = 0;
for(i = 0;i < globres.gl_pathc;i++)
{
if(path_noloop(globres.gl_pathv[i]))
sum+=mydu(globres.gl_pathv[i]);
}
//加上本身目录文件的大小
sum += statres.st_blocks;
globfree(&globres);
return sum;
}
int main(int argc,char **argv)
{
if(argc < 2)
{
fprintf(stderr,"Usage ...\n");
exit(1);
}
printf("%ld\n",mydu(argv[1])/2);
return 0;
}
运行结果如下: