#include
#include
#include
#include
#include
#include
#include
typedef int Myfn(const char *, const struct stat *, int);
enum{
FTW_F = 1,
FTW_D,
FTW_DNR,
FTW_NS
};
static int myDispose(const char *path);
static int myfn(const char *fpath, const struct stat *sb, int typeflag);
static int myDisposeNext(Myfn *myfn);
static char *cptPath; //complete path
static size_t cptPathLen = NAME_MAX;
static Myfn myfn;
static unsigned long int reg, dir, blk, fifo, chr, slink, sock;
static unsigned long int total;
static int myfn(const char *fpath, const struct stat *sb, int typeflag){
switch(typeflag){
case FTW_F:
total++;
switch(sb->st_mode & S_IFMT){
case S_IFDIR:
fprintf(stderr, "why dir here\n");
return(1);
case S_IFREG: reg++; break;
case S_IFBLK: blk++; break;
case S_IFCHR: chr++; break;
case S_IFIFO: fifo++; break;
case S_IFSOCK: sock++; break;
case S_IFLNK: slink++; break;
}
break;
case FTW_D:
total++;
dir++;
break;
case FTW_NS:
fprintf(stderr, "can not open %s, may be not have permission\n", fpath);
break;
case FTW_DNR:
fprintf(stderr, "can not read %s\n", fpath);
break;
default:
fprintf(stderr, "myfn() typeflag error!\n");
exit(1);
}
return 0;
}
static int myDisposeNext(Myfn *myfn){
struct stat statMsg;
DIR *dp;
struct dirent *dirMsg;
int ret;
size_t dirlen;
ret = lstat(cptPath, &statMsg);
if(ret < 0){
return(myfn(cptPath, &statMsg, FTW_NS));
}
if(!S_ISDIR(statMsg.st_mode)){ //not a dir
return(myfn(cptPath, &statMsg, FTW_F));
}
//dir
ret = myfn(cptPath, &statMsg, FTW_D);
dirlen = strlen(cptPath);
cptPath[dirlen] = '/';
cptPath[dirlen+1] = '<= pathLen){
cptPathLen *= 2;
if((cptPath = realloc(cptPath, cptPathLen)) == NULL){
perror("cptPath realloc()");
exit(1);
}
}
strncpy(cptPath, path, pathLen);
return(myDisposeNext(myfn));
}
int main(int argc, char **argv){
if(argc < 2){
fprintf(stderr, "Usage: ./mytfw path ... \n");
exit(1);
}
int i, ret;
for(i = 1; i < argc; i++){
ret = myDispose(argv[i]);
if(ret != 0){
fprintf(stderr, "error!\n");
break;
}
printf("------------------------------\n");
printf("----------%-10s----------\n", argv[i]);
printf("reg = %ld\n", reg);
printf("dir = %ld\n", dir);
printf("blk = %ld\n", blk);
printf("chr = %ld\n", chr);
printf("fifo = %ld\n", fifo);
printf("slink = %ld\n", slink);
printf("sock = %ld\n", sock);
printf("total = %ld\n", total);
printf("------------------------------\n");
printf("------------------------------\n");
reg = 0;
dir = 0;
blk = 0;
chr = 0;
fifo = 0;
slink = 0;
sock = 0;
total = 0;
memset(cptPath, 0, cptPathLen);
cptPathLen = NAME_MAX;
}
exit(0);
}
';
dp = opendir(cptPath);
if(dp == NULL){
return(myfn(cptPath, &statMsg, FTW_DNR));
}
while(1){
dirMsg = readdir(dp);
if(dirMsg == NULL){
break;
}
if(strcmp(dirMsg->d_name, ".") == 0 || strcmp(dirMsg->d_name, "..") == 0){
continue;
}
strcpy(&cptPath[dirlen+1], dirMsg->d_name);
ret = myDispose(cptPath);
if(ret != 0){
break;
}
}
cptPath[dirlen] = '\0';
closedir(dp);
return(ret);
}
static int myDispose(const char *path){
size_t pathLen = strlen(path);
if(cptPath == NULL){
if((cptPath = malloc(cptPathLen)) == NULL){
perror("cptPath malloc()");
exit(1);
}
}
while(cptPathLen
运行效果
运行环境:Ubuntu 21.10, gcc version 11.2.0
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)