The Pointer
The Pointer

Reputation: 2386

Printing all files within a directory and its subdirectories

My goal is to print all files within a directory and its subdirectories. If the path is a file, I print out the path. However, if the path is a directory, then I recursively call pathInfo(pathnm), where pathnm is the path. My reasoning for this is that eventually it will reach the last directory, in which case it will print all of the files in that directory. As it progresses towards the last directory, it will successively print out the files it encounters. Eventually, all of the files in a given path directory and its subdirectories will be printed.

The problem is that at runtime, the program fails to print file names. Instead, it prints continuous lines of rubbish, such as /Users/User1//././././././././././././. This occurs until the program exits with the error progname: Too many open files.

How can I determine what I am doing incorrectly, and how I can fix it so that the program behaves in the way I have described? I am new to programming.

pathInfo function

#include "cfind.h"

void getInfo(char *pathnm, char *argv[]) 
{
    DIR *dirStream; // pointer to a directory stream
    struct dirent *dp; // pointer to a dirent structure
    char *dirContent = NULL; // the contents of the directory
    dirStream = opendir(pathnm); // assign to dirStream the address of pathnm
    if (dirStream == NULL)
    {
        perror(argv[0]);
        exit(EXIT_FAILURE);
    }
    while ((dp = readdir(dirStream)) != NULL) // while readdir() has not reached the end of the directory stream
    {
        struct stat statInfo; // variable to contain information about the path
        asprintf(&dirContent, "%s/%s", pathnm, dp->d_name); // writes the content of the directory to dirContent // asprintf() dynamically allocates memory
        fprintf(stdout, "%s\n", dirContent);
        if (stat(dirContent, &statInfo) != 0) // if getting file or directory information failed
        {
            perror(pathnm);
            exit(EXIT_FAILURE);
        }
        else if (aflag == true) // if the option -a was given
        {
            if (S_ISDIR(statInfo.st_mode)) // if the path is a directory, recursively call getInfo()  
            {
                getInfo(dirContent, &argv[0]);
            }
            else if(S_ISREG(statInfo.st_mode)) // if the path is a file, print all contents
            {
                fprintf(stdout, "%s\n", dirContent);
            }
            else continue;
        }
        free(dirContent);
    }
    closedir(dirStream);
}

Upvotes: 1

Views: 434

Answers (1)

neuhaus
neuhaus

Reputation: 4094

Every directory contains an entry "." that points to itself. You must make sure to skip this entry (and also the ".." entry that points to the parent directory).

So for your example, add an extra condition to the line

if (S_ISDIR(statInfo.st_mode))

Upvotes: 4

Related Questions