Search code examples
crecursionmultiprocess

Recursive multi-process program in c


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.


Solution

  • 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!