2014-09-09 2 views
-2

나는 경로 이름을 사용하고 그 경로를 가로 지르는 프로그램을 작성하고 그것이 나오는 모든 파일 경로와 블록의 파일 크기를 인쇄 한 다음 디렉토리라면 dir 경로 이름과 크기를 블록 단위로 인쇄합니다.C에서 경로 통과

코드가 무한 루프로 끝나며 "상태를 가져 오지 못했습니다. 파일이 너무 많이 열립니다."라는 메시지가 계속 표시됩니다.

#include <dirent.h> 
#include <time.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
int main(int argc, char **argv){ 
    struct stat statbuf; 
    struct dirent *direntp; 
    DIR *dirp; 
    if(stat(argv[1], &statbuf) == -1){ 
     perror("Failed to get file status"); 
     return 1; 
    } 
    else if(argc != 2){ 
     perror("Invalid amount of arguments, showtreesize requires 1 pathname"); 
     return 1; 
    } 
    else{ 
     if(S_ISDIR(statbuf.st_mode) || S_ISREG(statbuf.st_mode)){ 
      printf("%s  %d", argv[1], depthfirstapply(argv[1],  sizepathfun(argv[1]))); 
     } 
     else{ 
      if(S_ISCHR(statbuf.st_mode)){ 
       printf("%s is a character special file.", argv[1]); 
      } 
      if(S_ISBLK(statbuf.st_mode)){ 
       printf("%s is a block special file", argv[1]); 
      } 
      if(S_ISFIFO(statbuf.st_mode)){ 
       printf("%s is a FIFO special file", argv[1]); 
      } 
      else{ 
       printf("%s is not a valid filetype", argv[1]); 
      } 
     } 
     return 0; 
    } 
} 


int sum = 0; 
int levelcount = 0; 
int isDirectory(char *path){ 
    struct stat statbuf; 
    if(stat(path, &statbuf) == -1) 
     return 0; 
    else 
     return S_ISDIR(statbuf.st_mode); 
} 

int depthfirstapply(char *path, int pathfun(char *path1)){ 
    struct dirent *direntp; 
    DIR *dirp; 
    if(isDirectory(path)){ 
     printf("%s\n", path); 
     if((dirp = opendir(path)) == NULL){ 
      perror ("Failed to open directory"); 
      return -1; 
     } 
     else{ 
      while((direntp = readdir(dirp)) != NULL) { 
       if(isDirectory(direntp->d_name)){ 
        int result = depthfirstapply(direntp->d_name, pathfun); 
        if (result > 0){ 
         sum += result; 
        } 
       } 
       else{ 
        if(pathfun(direntp->d_name) >= 0){ 
         sum += pathfun(direntp->d_name); 
        } 
       } 
      } 
      while ((closedir(dirp) == -1) && (errno == EINTR)) ; 
     } 
    } 
    else{ 
     sum += pathfun(path); 
    } 
    return sum; 
} 



int sizepathfun(char *path){ 
    struct stat statbuf; 
    if(stat(path, &statbuf) == -1){ 
     perror("Failed to get file status"); 
     return -1; 
    } 
    if(S_ISREG(statbuf.st_mode) == 0){ 
     return -1; 
    } 
    else{ 
     printf("%s  %d", path, statbuf.st_blocks); 
     return statbuf.st_blocks; 
    } 
} 
+0

왜'ftw()'를 쓰지 않으시겠습니까? – Barmar

답변

0

몇 가지 문제는 :

  1. 당신은 ... 항목을 생략해야합니다. 그렇지 않으면 동일한 디렉토리에서 루핑을 계속합니다.

  2. stat()이 아닌 lstat()isDirectory에 사용하십시오. 그렇지 않으면 루프가 생길 수있는 디렉토리에 대한 심볼릭 링크가 반복됩니다.

  3. 각 디렉토리 수준으로 내려갈 때 디렉토리 구성 요소를 이름에 연결해야합니다.

  4. depthfirstapply의 두 번째 인수는 함수로 간주됩니다. 그러나 main()에서는 sizepathfun(argv[1))으로 전화를 걸면 정수가 반환됩니다. 이 인수는 단지 sizepathfun이어야합니다. 형식 불일치로 인해 컴파일 경고가 표시되어야합니다.

POSIX는 이에 대한 표준 기능 집합 인 fts_XXX()을 제공합니다.

+0

도움을 많이 주셔서 감사합니다! 그것들은 내가 전혀 생각하고 있지 않은 것들이었다! 처음 2 번 변경했지만 여전히 동일한 오류가 발생합니다. 단 두 번 나타나고 세그먼트 오류가 있다고합니다. 내가 뭘 잘못했는지에 대한 다른 생각은 없습니까? –

+0

당신은'depthfirstapply'를 부정확 한 두 번째 인자와 함께 호출합니다. # 4가 답에 추가되었습니다. – Barmar

+0

도와 주셔서 대단히 감사합니다! 그것들을 고친 후에, 나는 마침내 그것이 일하도록했다. –

관련 문제