Home > Software engineering >  Why is only the first Child Process printing something out?
Why is only the first Child Process printing something out?

Time:11-17

The program I am working on is called myfile - It should find a file in a certain searchpath. You should also be able to search for multiple files and if so, I MUST create multiple child processes with fork(). The problem is, i dont get the expected outcome printed out. If I am searching for multiple files, only the first file gets "returned". I think it has something todo with the second for in the else statement. For debugging I am printing out every PID of the child processes. Is the problem maybe that the child processes are working with the same variables at the same time?

The Code: `

#include<iostream>
#include<dirent.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<stdlib.h>
using namespace std;
int main(int argc, char** argv)
{
    struct dirent *d;
    DIR *dr;
    dr = opendir(argv[1]);

    pid_t pid;
    int numberOfFiles = argc - 2;
    if(dr!=NULL){
        if(numberOfFiles == 1){
            // normal search without fork
            for(d=readdir(dr); d!=NULL; d=readdir(dr)){
                if(strcmp(d->d_name, argv[argc-1]) == 0){
                    cout << "<" << getpid() << ">: " << argv[argc-1] << ": <" << realpath(argv[argc-1], NULL) << ">" <<endl;
                }
            }
        }else{
            // search with fork
            for(int i = 2; i < argc; i  ){
                if(fork() == 0){
                    cout << "Current PID: " << getpid() << " " << argv[i] <<endl;
                    for(d=readdir(dr); d!=NULL; d=readdir(dr)){
                        if(strcmp(d->d_name, argv[i]) == 0){
                            cout << "Current i=" << i << " "<< "<" << getpid() << ">: " << argv[i] << ": <" << realpath(argv[i], NULL) << ">" <<endl;
                        }
                    }
                    exit(0);
                }
            }
            for(int i=0; i < numberOfFiles; i  ){
                wait(NULL);
            }
        }
    }else
        cout<<"\nError Occurred!"<<endl;
    cout<<endl;
    return 0;
}

` Screenshot of output in terminal: enter image description here

The problem is, i dont get the expected outcome printed out. If I am searching for multiple files, only the first file gets "returned". I think it has something todo with the second for in the else statement. For debugging I am printing out every PID of the child processes. Is the problem maybe that the child processes are working with the same variables at the same time?

CodePudding user response:

Looks like a problem with opendir, readdir, and reusing variables. I cut your program down to:

int main(int argc, char **argv)
{
    struct dirent *d;
    DIR *dr;
    dr = opendir(argv[1]);

    for (int i = 2; i < argc; i  )
    {
        if (fork() == 0)
        {
            cout << "Current PID: " << getpid() << " " << argv[i] << endl;
            for (d = readdir(dr); d != NULL; d = readdir(dr))
            {
                cout << getpid() << "\t" << d->d_name << endl;
            }
            exit(0);
        }
    }

    for (int i = 0; i < argc - 2; i  )
        wait(NULL);
}

And got this output (from ./testfork ../bla 1 2):

Current PID: 17197 1
Current PID: 17198 2
17198   test.txt
17198   ..
17198   .

Which shows that once one process has read to end with readdir, then the other gets nothing. However, if I move the call to opendir to after the fork:

int main(int argc, char **argv)
{
    struct dirent *d;
    DIR *dr;

    for (int i = 2; i < argc; i  )
    {
        if (fork() == 0)
        {
            dr = opendir(argv[1]);  // <- Here
            cout << "Current PID: " << getpid() << " " << argv[i] << endl;
            for (d = readdir(dr); d != NULL; d = readdir(dr))
            {
                cout << getpid() << "\t" << d->d_name << endl;
            }
            exit(0);
        }
    }

    for (int i = 0; i < argc - 2; i  )
        wait(NULL);
}

The the output becomes:

Current PID: 17751 1
17751   test.txt
17751   ..
17751   .
Current PID: 17752 2
17752   test.txt
17752   ..
17752   .

I don't quite understand why this happens, since the way fork works should ensure that each process get their own copy of the memory (though possibly only after writing to it). So when one process modifies dr, then that change should not be reflected in the other processes.

Perhaps it is due to dr actually being changed through system calls (by way of readdir), and not by the process directly?

  • Related