这是一个C程序,用于递归地导航和输出目录和常规文件.它在我的
Linux机器上编译并运行正常.但是在Solaris上,dit-> d_type == 8检查和其他类似的检查不起作用,因为没有d_type字段.我读到这个问题的答案是使用S_ISREG()和S_ISDIR()宏,但是它们在我的代码当中没有任何办法.我评论了在我的Linux机器上工作的线条.
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
void helper(DIR *,struct dirent *,struct stat,char *,int,char **);
void dircheck(DIR *,char **);
int main(int argc,char *argv[]){
DIR *dip;
struct dirent *dit;
struct stat statbuf;
char currentPath[FILENAME_MAX];
int depth = 0; /*Used to correctly space output*/
/*Open Current Directory*/
if((dip = opendir(".")) == NULL)
return errno;
/*Store Current Working Directory in currentPath*/
if((getcwd(currentPath,FILENAME_MAX)) == NULL)
return errno;
/*Read all items in directory*/
while((dit = readdir(dip)) != NULL){
/*Skips . and ..*/
if(strcmp(dit->d_name,".") == 0 || strcmp(dit->d_name,"..") == 0)
continue;
if(stat(currentPath,&statbuf) == -1){
perror("stat");
return errno;
}
/*Checks if current item is of the type file (type 8) and no command line arguments
if(dit->d_type == 8 && argv[1] == NULL)*/
if(S_ISREG(statbuf.st_mode) && argv[1] == NULL)
printf("%s (%d bytes)\n",dit->d_name,(int)statbuf.st_size);
/*If a command line argument is given,checks for filename match
if(dit->d_type == 8 && argv[1] != NULL)*/
if(S_ISREG(statbuf.st_mode) && argv[1] != NULL)
if(strcmp(dit->d_name,argv[1]) == 0)
printf("%s (%d bytes)\n",(int)statbuf.st_size);
/*Checks if current item is of the type directory (type 4)
if(dit->d_type == 4)*/
if(S_ISDIR(statbuf.st_mode))
dircheck(dip,dit,statbuf,currentPath,depth,argv);
}
closedir(dip);
return 0;
}
/*Recursively called helper function*/
void helper(DIR *dip,struct dirent *dit,struct stat statbuf,char currentPath[FILENAME_MAX],int depth,char *argv[]){
int i = 0;
if((dip = opendir(currentPath)) == NULL)
printf("Error: Failed to open Directory ==> %s\n",currentPath);
while((dit = readdir(dip)) != NULL){
if(strcmp(dit->d_name,"..") == 0)
continue;
stat(currentPath,&statbuf);
/*if(dit->d_type == 8 && argv[1] == NULL){*/
if(S_ISREG(statbuf.st_mode) && argv[1] == NULL){
for(i = 0; i < depth; i++)
printf(" ");
printf("%s (%d bytes)\n",(int)statbuf.st_size);
}
/*if(dit->d_type == 8 && argv[1] != NULL){*/
if(S_ISREG(statbuf.st_mode) && argv[1] != NULL){
if(strcmp(dit->d_name,argv[1]) == 0){
for(i = 0; i < depth; i++)
printf(" ");
printf("%s (%d bytes)\n",(int)statbuf.st_size);
}
}
/*if(dit->d_type == 4)*/
if(S_ISDIR(statbuf.st_mode))
dircheck(dip,argv);
}
}
void dircheck(DIR *dip,char *argv[]){
int i = 0;
strcat(currentPath,"/");
strcat(currentPath,dit->d_name);
/*If two directories exist at the same level the path
is built wrong and needs to be corrected*/
if((chdir(currentPath)) == -1){
chdir("..");
getcwd(currentPath,FILENAME_MAX);
strcat(currentPath,"/");
strcat(currentPath,dit->d_name);
for(i = 0; i < depth; i++)
printf (" ");
printf("%s (subdirectory)\n",dit->d_name);
depth++;
helper(dip,argv);
}
else{
for(i =0; i < depth; i++)
printf(" ");
printf("%s (subdirectory)\n",dit->d_name);
chdir(currentPath);
depth++;
helper(dip,argv);
}
}
解决方法
你正在使用S_ISREG()和S_ISDIR(),你只是用错了的东西.
在你的while((dit = readdir(dip))!= NULL)循环中,你正在一遍又一遍地调用currentPath上的stat,而不改变currentPath:
if(stat(currentPath,&statbuf) == -1) {
perror("stat");
return errno;
}
您不应该将斜杠和dit-> d_name附加到currentPath以获取要统计的文件的完整路径? Methinks也需要与其他统计调用类似的更改.