开发者

Problem reading directories in C

开发者 https://www.devze.com 2023-04-05 19:57 出处:网络
I am writing a simple C program that receives a directory as an argument and displays the files in this directory and also his subdirectories. I wrote a \"recursive\" function for doing that. But for

I am writing a simple C program that receives a directory as an argument and displays the files in this directory and also his subdirectories. I wrote a "recursive" function for doing that. But for an unknown reason, my program fails at the stat function. Here is my program :

    #define _POSIX_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>


void display_directory(char* path){

  DIR* directory = opendir(path);
  if( directory == NULL){
    printf("opendir failure for %s\n", path);
    exit(1);
  }


 struct dirent* dirent;
 struct stat stat_info;

 while((dirent = readdir(directory)) != NULL){
   printf("[%s]\n", dirent->d_name);
   if(stat(dirent -> d_name, &stat_info) == -1){
     printf("readdir error for %s\n", dirent->d_name);
     exit(1);
   }
   if(S_ISREG(stat_info.st_mode)){
       printf("File: %s \n", dirent -> d_name); 
   }
   if(S_ISDIR(stat_info.st_mode)){
     if(strncmp(dirent->d_name, "..",2)){
       printf("Directory : %s\n", dirent->d_name);
       display_directory(dirent->d_name);
     }  
    }

 }

 closedir(directory);
}

int main(int argc, char* argv[]){

char* path;

if(argc > 1){
 path = argv[1];
} else {
 path = ".";
}

display_directory(path);

 return EXIT_SUCCESS;
}

For instance, if in my directory A, I have a1, a2, a3 and .., it reads first the .. directory, and when it reads the directory a1, the stat function fails.

Can someone tells me what is not correct with my code.

[EDIT] I included <errno.h> as many of you suggest and after running the program, I have the error Too many open files.

    #define _POSIX_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>


void display_directory(char* path){

  DIR* directory = opendir(path);
  if( directory == NULL){
    printf("opendir failure for %s --> %s\n", path, strerror(errno));
    exit(1);
  }


 struct dirent* dirent;
 struct stat stat_info;

 while((dirent = readdir(directory)) != NULL){
   printf("[%s]\n", dirent->d_name);
   if(stat(dirent->d_name, &stat_info)){
     printf("readdir error for %s ---> %s\n", dirent->d_name, strerror(errno));
     continue;
   }
   if(S_ISREG(stat_info.st_mode)){
       printf("Fichier : %s \n", dirent->d_name); 
   }
   if(S_ISDIR(stat_info.st_mode)){
     if(strncmp(dirent->d_name, "..",2)){
       printf("Directory : %s\n", dirent->d_name);
       display_directory(dirent->d_name);
     }  
    }

 }

 closedir(directory);
}

int main(int argc, char* argv[]){

char* path;开发者_运维知识库

if (argc > 2) { 
 fprintf(stderr, "Usage: %s [directory]\n", argv[0]); 
 exit(1); 
}

path = argv[1];


display_directory(path);

 return EXIT_SUCCESS;
}

The output of the program :

[..]
[mykill.c]
readdir error for mykill.c ---> No such file or directory
[.]
Directory : .
[..]
[.]
Directory : .
[..]
[.]
Directory : .
[..]

...
...
Directory : .
opendir failure for . --> Too many open files

mykill.c is a file in the directory that was passed as an argument.


I have a pretty good idea what's wrong, but I want to tell you how to debug this for yourself, first. Change this code ...

if(stat(dirent -> d_name, &stat_info) == -1){
  printf("readdir error for %s\n", dirent->d_name);
  exit(1);
}

... to read instead ...

if (stat(dirent->d_name, &stat_info)) {
    printf("%s: %s\n", dirent->d_name, strerror(errno));
    continue;
}

You will need to add to the include list

#include <errno.h>

Run the program again. If you don't see from the output what the problem is, then edit the COMPLETE, UNEDITED output into your question and we'll go from there.


if(S_ISDIR(stat_info.st_mode)){
 if( !strcmp(dirent->d_name, ".")) continue;
 if( !strcmp(dirent->d_name, "..")) continue;

 printf("Directory : %s\n", dirent->d_name);
 display_directory(dirent->d_name);
}


You are making stat only with filename (without full path), add full path to the filename or change working directory before calling stat.


Use nftw().

0

精彩评论

暂无评论...
验证码 换一张
取 消