Bu, yinelemeli olarak dizinlere ve düzenli dosyalara gitmek ve çıktı almak için yazdığım bir C programıdır. Linux makinemi derler ve iyi çalışır. Ama Solaris üzerinde, dit->d_type == 8
denetimi ve diğer benzerleri çalışmaz, çünkü d_type
alanı yok. Bu soruna okuduğum bir cevap, S_ISREG()
ve S_ISDIR()
makrolarını kullanmaktır, ancak şu anda kodumda oldukları gibi çalışmıyorlar. Linux makinemde çalışan hatlara yorum yaptım. Doğru S_ISREG()
ve S_ISDIR()
kullandığınızS_ISREG() ve S_ISDIR() POSIX Makrolar nasıl kullanılır?
#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 *, struct dirent *, struct stat, char *, int, 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", dit->d_name, (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 || 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", dit->d_name, (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", dit->d_name, (int)statbuf.st_size);
}
}
/*if(dit->d_type == 4)*/
if(S_ISDIR(statbuf.st_mode))
dircheck(dip, dit, statbuf, currentPath, depth, argv);
}
}
void dircheck(DIR *dip, struct dirent *dit, struct stat statbuf,
char currentPath[FILENAME_MAX], int depth, 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, dit, statbuf, currentPath, depth, argv);
}
else{
for(i =0; i < depth; i++)
printf(" ");
printf("%s (subdirectory)\n", dit->d_name);
chdir(currentPath);
depth++;
helper(dip, dit, statbuf, currentPath, depth, argv);
}
}
Sorunun artık anlamlı olmadığı için kodu orijinaline geri yükledim. Çalışma koduna katkıda bulunmanız harika, ama bu soruya değil, bir cevaba ait. Mu'nin çözümünü uygulayan eksiksiz bir kod yayınlamaya değer olduğunu düşünüyorsanız, lütfen yanıt olarak gönderin. – Gilles
Bu bir yıldan fazla bir süredir böyle oturuyor ve iyi bir görüşe sahip. Doğru kodun kaldırılması için bir neden yoktur çünkü buralarda insanlar buraya ilgi duyacaklardır (ve sorunu çözdüler). Kırılan çözümün olması hiç kimseye yardım etmiyor. Bunu değiştirmek isterseniz, en azından çözümü önce yanıt olarak yapıştırın. – zalberico
Bu, "ağaç" ile aynı mı? –