Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Trying to emulate recursive ls command(very new to c)

  1. Feb 23, 2005 #1
    I'm very new to programming in c, and I'm trying to write a program that recursivley lists all the files in a directory, as well as all of the subdirectores and their files. I'm having some problems.

    On my first go I was able to get all of the files of the current directory to be listed. That was easy. I'm having trouble getting my program to jump into all of the subdirectories and then get back to the original directory and list its files. My code seems to jump into the first subdirectory and list its files, but it ends with a Segmentation fault. I googled the error and found out what it means, but I have no idea how to go about remedying it.


    Code (Text):

    #include <stdio.h>
    #include <errno.h>
    #include <sys/time.h>
    #include <sys/times.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <limits.h>
    #include <dirent.h>
    #include <unistd.h>


    int x = 0;
    struct dirent *dp;

    void listit(DIR *dirp,DIR *tdirp,int level){
      errno = 0;
      if (!(dp = readdir(dirp))) {
        if (errno == 0) {
          printf("porblem\n");
        }
        else {
          printf("Error reading entry in directory\n");
          return;
        }
      }
      else {
        tdirp = (opendir(dp->d_name));
        if(tdirp){
          if(!((strcmp(dp->d_name,".")) == 0 || strcmp(dp->d_name,"..") == 0)){
        printf("-----------NEW DIRECTORY--------------\n");
        printf(" %s\n",dp-> d_name);
        dirp = opendir(dp->d_name);
        listit(dirp,tdirp,level);
           }
           else{
         printf("%s\n",dp->d_name);
         listit(dirp,tdirp,level);
           }
        }
        printf("%s\n",dp->d_name);
        listit(dirp,tdirp,level);
      }
    }
       


    int main(int argc, char *argv[]){
       struct timeval t;
       int i, status = 0;
       int count = 0;
       int level = 0;
       DIR *dirp;
       DIR *tdirp;
       dirp = opendir(argv[1]);
       
       if (argc < 2) { exit(-1); }

     if ((status = gettimeofday(&t,0)) != 0) {
          printf("Error - time call failed\n");
       }
         
       if (!dirp) {
          if (access(argv[1],F_OK)) {
             printf("Error - couldn't interpret %s as directory.\n", argv[1]);
             printf("----------------------------------\n\n");
          }
          else {
             printf("%s\n", argv[1]);
             printf("----------------------------------\n\n");
          }
       }
       else {
          printf("Contents of directory %s:\n", argv[1]);
           listit(dirp,tdirp,level);    

       }
    }
     
     
  2. jcsd
  3. Feb 23, 2005 #2

    NateTG

    User Avatar
    Science Advisor
    Homework Helper

    The c compiler is complaining because there is a 'porblem' in your code. (Just kidding.)

    I don't see anything particularly obvious. I'm guessing that dp gets clobbered somwhere. Are you sure it should be global?
     
  4. Feb 23, 2005 #3

    chroot

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Nate's got it. It's a very bad idea for a recursive function to use globals, by the way.

    - Warren
     
  5. Feb 23, 2005 #4

    dduardo

    User Avatar
    Staff Emeritus

    If you can include stdlib.h then you can simply do this:

    system("ls -R")
     
  6. Feb 23, 2005 #5

    NateTG

    User Avatar
    Science Advisor
    Homework Helper

    That wouldn't exactly be emulating ls now, would it?
     
  7. Feb 23, 2005 #6

    dduardo

    User Avatar
    Staff Emeritus

  8. Feb 23, 2005 #7
    I changed dp to a local and passed it into listit. Directores still aren't getting read though?

    Maybe my understanding of what's going on is incorrect.

    In my main method I have dirp = opendir(argv[1]);, which reads in a directory name from the command line and attempts to open the directory.

    If dirp is a valid directory name, it opens the directory and then passes the name up to function listit.

    In listit, it checks to see if there are files in the directory ( the line if (!(dp = readdir(dirp))) { ), if so, it goes to the else where tdirp reads in the first file in the directory and checks if it is a sub-directory.

    If it is a directory, it checks to see if the directory is "." or "..". If it is not, it prints the directory name and opens it, followed by a recursive call to listit. So, listit gets called with the new directory name and the whole thing starts over.

    If it's "." or "..", it calls listit again. dp is set to the next file in the directory and it starts again.

    If it's not a directory, it's a file, and the file name is printed. listit is called and the whole thing starts over.

    Except new directories are never entered. gah!
     
  9. Oct 13, 2009 #8
    Hi:
    if (!(dp = readdir(dirp)))

    shouldn't this be:
    if (!(dp == readdir(dirp)))?
     
  10. Oct 14, 2009 #9

    rcgldr

    User Avatar
    Homework Helper

    You might consider using a loop in listit() to process each "current" directory, then recursively calling listit() for each sub-directory encountered. You already mentioned changing dp to be a local variable. I don't understand why you pass dirp or tdirp or level as parameters, as dirp also needs to be a local variable. The only thing you need to pass to listit() is the name string for the directory. Then the local copy of dirp gets the result from doing an opendir(...name...).

    Another alternative is to have two loops in listit(). The first loop processes all files, the second loop processes all directories (via recursive calls). This keeps all the files in a directory adjacent to each other the list.
     
  11. Apr 9, 2010 #10
    If you didn't find the solution yet.
    when you find new directory you have to call.

    chdir(dir); in order to enter il.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?



Similar Discussions: Trying to emulate recursive ls command(very new to c)
  1. Recursion in C (Replies: 12)

  2. New to C/C++ (Replies: 4)

  3. MOVE command, C:, C:\ (Replies: 10)

Loading...