MrHappyAsthma
MrHappyAsthma

Reputation: 6522

C Unix - fork(), execl() and pipe in a loop

I want to preface this with the fact that I have no formal education in the use of pipes, so this is my first venture. Not to mention that I couldn't find any similar questions to my situation.

Note: This IS part of a larger project for a school assignment, so I am NOT asking for anyone to do this for me. I would just like some direction/helpful code segments. (I have tried to make this as generic as possible to avoid "cheater" remarks.)

I am trying to run a for-loop over int k elements in which a parent process spawns off k children with fork() and execl(), and then use a pipe() to send the output back to the parent. Here is some generic code that I am trying to use and the error/problem in which I encounter:

Note: helloworld= an executable compiled with GCC that produces printf("hello world\n");

int k = 10; //The number of children to make
int fd[2]; //Used for each pipe
int readFromMe[k]; //Holds the file IDs of each pipe fd[0]
int writeToMe[k]; //Holds the file IDs of each pipe fd[1]
int processID[k]; //Holds the list of child process IDs

//Create children
int i;
for(i = 0; i < k; i++)
{
    if(pipe(fd) == -1)
    {
        printf("Error - Pipe error.\n");
        exit(EXIT_FAILURE);
    }

    //Store the pipe ID
    readFromMe[i] = fd[0];
    writeToMe[i] = fd[1];

    if((processID[i] = fork()) == -1)
    {
        fprintf(stderr, "fork failure");
        exit(EXIT_FAILURE);
    }

    //If it is a child, change the STDOUT to the pipe-write file descriptor, and exec
    if(processID[i] == 0)
    {
        dup2 (writeToMe[i], STDOUT_FILENO);
        close(readFromMe[i]);

        execl("./helloworld", (char *)0);
    }

    //If it is the parent, just close the unnecessary pipe-write descriptor and continue itterating
    else
    {
        close(writeToMe[i]);
    }
}

//Buffer for output
char output[100000];

//Read from each pipe and print out the result  
for(i = 0; i < k; i++)
{
    int r = read(readFromMe[i], &output, (sizeof(char) * 100000));

    if(r > 0)
    {
        printf("result = %s\n", output);
    }

    close(readFromMe[i]);
}   

I get no output from my program at all, so I am trying to figure out why this issue is occurring.

Upvotes: 1

Views: 1846

Answers (2)

clemej
clemej

Reputation: 2563

Try printing the value of 'r' in your printout function. I suspect the read is returning an error (perhaps EPIPE) that you're not seeing. Also, you example code is trying to printf 'c', not output like it looks like you meant.

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409166

Probably unrelated, but you call execl wrong. The extra arguments after the program is what will the the argv array to the other programs main function. And as you know it always have one entry, the program name. So you need to call it like this:

execl("./helloworld", "helloworld", NULL);

More related to your problem, you should also check for errors, it might actually fail.

Upvotes: 1

Related Questions