I am currently attempting to write a program that finds the size of a directory tree as well as the size of all subdirectories within it by creating a thread for each new subdirectory and using that thread to find the size of the subdirectory. It's a pretty simple program, but it's really hard to debug. I am having a TON of issues with S_ISDIR not working as intended (regular files are passing the if statement and my program is trying to change dir into regular files). Below is the code that I have for the problem. I would like to have each parent directory wait for the subdirectories to finish, but don't want each subdirectory to wait for the next one.
#define NAMESIZE 256
#define NUM_THREADS 100
#define MAX_PATH_LENGTH 500
int totalSum = 0;
pthread_mutex_t sum_mutex ;
pthread_mutex_t thread_mutex ;
void *findSize(void *p)
{
int levelSum = 0, numberThreads = 0, i = 0;
DIR *dir ;
struct dirent *entry ;
struct stat entry_stat ;
char cwd[2049] ;
char threads[NUM_THREADS] ;
char paths[NUM_THREADS][MAX_PATH_LENGTH];
char *path = (char*)p ;
// change into the directory that was passed in
if(chdir (p) == -1)
{
perror("chdir");
exit(1);
}
// get current working directory
if(!getcwd (cwd, 2049))
{
perror("getcwd") ;
return;
}
// open the directory to get entries within it
dir = opendir(".") ;
if(!dir)
{
perror("Cannot read directory");
return;
}
while((entry = readdir(dir)))
{
// call stat on the current entry in the directory
if(stat (entry->d_name, &entry_stat) == -1)
{
perror("stat error");
}
// skip the . and .. directories
if(strcmp (entry->d_name, ".") == 0)
continue;
if(strcmp (entry->d_name, "..") == 0)
continue;
// check if current entry is a directory
if(S_ISDIR (entry_stat.st_mode))
{
pthread_mutex_lock(&thread_mutex) ;
strcpy(paths[numberThreads], cwd) ;
strcat(paths[numberThreads], "/") ;
strcat(paths[numberThreads], entry->d_name) ;
pthread_t temp ;
// create new thread in threads array
if (pthread_create(&temp, NULL, findSize, (void *)paths[numberThreads]))
{
fprintf("failed to create thread for directory %s\n ", paths[numberThreads]) ;
exit(1) ;
}
threads[numberThreads] = temp;
// increment the number of threads created on this level of the directory tree
numberThreads++ ;
pthread_mutex_unlock(&thread_mutex) ;
}
if(S_ISREG(entry_stat.st_mode))
{
pthread_mutex_lock(&sum_mutex) ;
int fileSize = entry_stat.st_size ;
levelSum += fileSize ;
totalSum += fileSize ;
pthread_mutex_unlock(&sum_mutex) ;
}
}
void *status ;
for(i = 0; i < numberThreads; i++)
{
pthread_join(threads[i], NULL) ;
}
}
In the main, I simply do pthread_create with my function findSize and the path that the user passes in. I get lots of stat errors, but I can't figure how to fix them..