Thread: PLEASE HELP with fork() and execl() linux functions in c++ code

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    16

    PLEASE HELP with fork() and execl() linux functions in c++ code

    my main program must accept the names of input and output text files as command line arguments. it should create a pipe and then create 2 other children processes. the pipe is for communication between the children. after the children are created the parent must wait for children to complete before exiting with wait() function.

    the first child process should replace its process image (with execl() function) with a read program that will open the specified input file, read it using the read() function, and write the contents to a pipe.

    the second child process should replace its image with a write program that will read the data from pipe and then write to specified output file.

    the read program should read in 512 characters at a time from the file. the read program should terminate after processing the file. the write program should exit once all of the data is written to the output file.

    I am unsure where the second fork() function should go for one thing. when i run my program my output file is overwritten with just blank space which leads me to believe my write buffer is blank, so it is never getting the data from the pipe. also, how does the execl() function work exactly? in my messing around it seems like nothing executes after the execl() function call in a given if block.

    Code:
    //parent
    
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
            int rc, rc2, ptest;
            int aipipe[2];
            cout << "before child" << endl;
            ptest = pipe(aipipe);
            rc = fork();
            cout << rc << endl;
            cout << ptest << endl;
    
            if (rc == 0)
            {
    
                    char readbuffer[512];
                    sprintf(readbuffer, "%d", aipipe[1]);
                    cout << "in first child" << endl;
                    execl("./reader", "reader", argv[1], readbuffer, NULL);
    
            }
    
            else if (rc == -1)
            {
                    cout << "fork call error" << endl;
    
            }
    
    
    
            cout << "hey" << endl;
            rc2 = fork();
            char writebuffer[512];
    
            if (rc2 == -1)
            {
                    cout << "fork call error" << endl;
            }
            else if (rc2 == 0)
            {
                    cout << "in second child" << endl;
                    execl("./writer", "writer", argv[2], writebuffer, NULL);
            }
    
    
            close(aipipe[0]);
            close(aipipe[1]);
            wait();
            wait();
    
            return 0;
    }
    
    
    
    
    
    
    
    
    
    
    
    //reader
    
    include <iostream>
    #include <fstream>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
            cout << "in reader" << endl;
            char readbuffer[512];
            int ipipefd = atoi(argv[2]);
            ifstream ifs(argv[1]);
            ifs.read(readbuffer, sizeof(readbuffer));
            write(ipipefd, readbuffer, ifs.gcount());
    
            return 0;
    }
    
    
    
    
    
    
    
    
    
    
    
    
    //writer
    
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
            cout << "in writer" << endl;
            char writebuffer[512];
            int rc;
            int ipipefd = atoi(argv[2]);
            ofstream ofs(argv[1]);
            rc = read(ipipefd, writebuffer, sizeof(writebuffer));
            ofs.write(writebuffer, rc);
    
    
    
            return 0;
    }

  2. #2
    Registered User
    Join Date
    Mar 2008
    Location
    Coimbra, Portugal
    Posts
    85
    I haven't read your code in detail yet. Like you said, execl replaces the current process image, which means that nothing past execl will be executed, unless it fails. It's similar to "invoking a program and dying", but what you do is "replace yourself with a new program".

    Just browsing through the code in a quick manner, I am curious about something:

    Code:
    close(aipipe[0]);
    close(aipipe[1]);
    In here, you close both pipes. Now, if none of the execl() calls fails, this will be run in the main application. Since you do not have any wait() function before that, here's whats happening:

    Program Starts
    -----------fork() -----------execl() -------------- new program
    -----------fork() -----------execl() -------------- new program 2
    -----------close pipes

    But you're closing the pipes as soon as the second program is up and running, which means that they won't be able to communicate!

    Note: I am not familiar with pipes. I might have misunderstood part of the code.
    Last edited by Jorl17; 09-22-2010 at 05:14 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fork, execv, spawn, or something else?
    By DavidP in forum C++ Programming
    Replies: 8
    Last Post: 01-26-2009, 04:25 PM
  2. fork(), exit() - few questions!
    By s3t3c in forum C Programming
    Replies: 10
    Last Post: 11-30-2004, 06:58 AM