Reputation: 53
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
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);
}
}
}
}
Upvotes: 2