Ben
Ben

Reputation: 53

Communicating between a child process and a parent process

I'm trying to communicate between two processes, a parent process that sends instructions and a child process that returns a response.

    void create_player(Game *g, Player *p, int player, char* command) {

       int send[2];
       int receive[2];
       int file;

        if(pipe(send)!=0) {
            _exit(99);
        }
        if(pipe(receive)!=0) {
            _exit(99);
        }

        g->player[player].id = fork();

        if(g->player[player].id < 0) {
            fprintf(stderr, "Unable to start subprocess\n");
            fflush(stderr);
            exit(5);
        }

        //Parent process
        else if(g->player[player].id>0) {
            g->player[player].send = fdopen(send[1], "w");
            g->player[player].receive = fdopen(receive[0], "r");

            close(send[0]);
            close(receive[1]);

        //Child process
        }  else {

           close(send[1]);
           close(receive[0]);
           dup2(send[0], 0);
           dup2(receive[1], 1);
           close(send[0]);
           close(receive[1]);

           file = open("/dev/null", O_WRONLY);

           for(i =0; i < player; i++) {
                fclose(g->player[i].send);
                fclose(g->player[i].receive);
            }

            char width[1024];
            char playerId[26];
            char numOfPlayers[26];
            char seed[1024];
            char numOfCarriages[1024];

            sprintf(seed, "%d", g->seed);
            sprintf(width, "%d", g->numOfCarriages);
            sprintf(playerId, "%d", player);
            sprintf(numOfPlayers, "%d", g->numOfPlayers);

            char* args[] = {command, numOfPlayers, playerId, width, seed, NULL};

            execlp(command, command, numOfPlayers, playerId, width, seed, (char*) 0);

            _exit(99);

}

When I run the code block to make the child processes, none of the messages are sent through (Parent stdout -> child stdin). I've added some examples to show how I'm handling the messaging. Any help would be greatly appreciated.

In the parent process: Parent Process sends message to child process

//Send message to start the game
void send_startGame(Game *g) {
    fprintf(g->player[g->currentPlayer].send, "startGame\n");
    fflush(g->player[g->currentPlayer].send);
}

In the child process: child message receives message from parent

void read_message(Game *g) {
    char message[2048];

    if(fgets(message, 2048, stdin) == NULL) {
        fprintf(stderr, "Error in message\n");
    }

    //Receive start game message
    if(strncmp("startGame\n", message, 9)==0){
        start_game(g);
    }

}

Upvotes: 0

Views: 1606

Answers (1)

mpromonet
mpromonet

Reputation: 11963

Try to reduce your code, there is wrong close in the child code :

       close(send[1]);
       dup2(send[0], 0);
       close(send[0]);

After the dup2, the filedescriptor send[0] is no more related to the send pipe input, and it could close unexpectly an other filedescriptor in the child process.

Your code doesnot make communication from stdout of parent to stdin of child. Hereafter a small sample that redirect stdout of parent to input of pipe and output of pipe to stdin of child.

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv) {
    int send[2];
    if(pipe(send)!=0) {
        perror("pipe");
    } else {
        int pid = fork();
        if(pid < 0) {
            perror("fork");
        }
        else if(pid>0) {
            //Parent process
            close(send[0]);  // close pipe input 
            dup2(send[1], 1); // replace stdout with pipe output

            // send message to child
            fprintf(stdout, "send to child\n");
            fflush(stdout);
        }  else {
            //Child process                     
            close(send[1]);      // close pipe output                       
            dup2(send[0], 0); // replace stdin with pipe input

            char message[2048];
            if(fgets(message, 2048, stdin) != NULL) {
                fprintf(stderr, "message from parent:%s", message);
            }
        }
    }
}

Ideone link

Upvotes: 2

Related Questions