The Pointer The Pointer - 1 month ago 11
C Question

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
.

I would appreciate input on what I am doing incorrectly and how I can fix it so that the program behaves in the way I have described. Please structure your answers in a way that is clear to someone new to programming.

Thank you.

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);
}

Answer

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))