I am working on a fairly simple program that should print out a file tree given a path. The program worked with just straight recursion but when I modified it to fork a new child process to iterate over each new directory I started getting some weird output. It appears that processes are being allowed to move backwards to their parent directory.
I have been testing it on a small sample folder called test. Test contains 2 files (testFile1 and testFile2) and a folder (testSub). The folder testSub only contains 2 files (testSubFile1 and testSubFile2). As far as I can tell, the child process that is supposed to iterate through the testSub folder is doing that and then moving up a directory to the test folder and iterating through that.
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
int recFork(char *path){
/*int key = rand() % 113;
printf("--------\n--------\n");
printf("New function\n");
printf("Key: %d\n", key);
printf("path: %s\npid: %d\n", path, getpid());
printf("--------\n--------\n");*/
int status;
pid_t pID = 1;
char name[1024];
struct stat statbuf;
if(stat(path, &statbuf) == -1)
return -1;
/* if the item is a file */
if(S_ISREG(statbuf.st_mode)){
printf("pID: %d ", getpid());
printf("%s\t%8ld\n", path, statbuf.st_size);
}
/* if the item is a directory */
else if((statbuf.st_mode & S_IFMT) == S_IFDIR){
pID = fork();
if(pID > 0){ //parent
//printf("Forked child with pID: %d\n", pID);
waitpid(pID, &status, WUNTRACED);
//printf("Killed: %d\n", pID);
}
else if(pID == 0){ //child
//printf("Child: %d\n", getpid());
DIR *dir;
struct dirent *dp = NULL;
if ((dir = opendir(path)) == NULL){
printf("Cannot open %s\n", path);
exit(EXIT_FAILURE);
}
else{
printf("DIR: %s/\n", path);
while((dp = readdir(dir)) != NULL){
//printf("pID: %d key: %d dp = %s\n", getpid(), key, dp->d_name);
if(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
continue;
sprintf(name, "%s/%s", path, dp->d_name);
//printf("Process: %d Key: %d\n", getpid(), key);
//printf("I was passed: %s\n", path);
//printf("Calling recFork(%s)\n\n", name);
recFork(name);
}
closedir(dir);
}
}
else{ //failed to fork
printf("Failed to fork\n");
exit(EXIT_FAILURE);
}
}
//printf("Returning from : %d with key: %d\n", getpid(), key);
return 0;
}
The code includes quite a few commented out printf statements that I was using to try and debug what was going on. Honestly I'm just at a loss and I don't know who else to ask. I really would like to learn what I am doing wrong so if someone can point me in the right direction that would be much appreciated.
I figured it out!
The issue was because a child was forked x number of levels deep in recursive statements and though I know each child is identical to its parent I didn't think that the child would be x levels deep in its own recursive pile.
Before a child would return it had to cycle back out of all of the recursive calls. I solved the issue by adding the statement exit(EXIT_SUCCESS);
right after the closedir(dir);
statement so instead of returning through all of the levels of recursion it would just exit once it finished its own directory.
Thanks everyone for your help along the way!