I'd like to send a message from the parent process to one of the child processes (child).
The message text is one of the three city names stored in an array of strings (cities).
The array pointer is dynamically allocated at the beginning of the main() function.
I determine the choosen city name by using srand(time(NULL)); and rand() % 3.
However, "Child terminates" and "Parent terminates" are not displayed.
I'd like to find out why. Any help is greatly appreciated!
Also, how would it be possible to send messages to both children?
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <wait.h>
#include <time.h>
struct message
{
long mtype;
char *mtext;
};
void handler(int number)
{
printf("Signal with ID %d has arrived\n", number);
}
// sendig a message
int send(int msg_queue, char **cities)
{
srand(time(NULL));
unsigned k = rand() % 3;
struct message msg =
{ 5, cities[k] };
int status;
status = msgsnd(msg_queue, &msg, strlen(msg.mtext) + 1, 0);
if (status < 0)
perror("msgsnd");
return 0;
}
// receiving a message.
int receive(int msg_queue)
{
struct message msg;
int status;
status = msgrcv(msg_queue, &msg, 21, 5, 0);
if (status < 0)
perror("msgsnd");
else
printf("Code of received message: %ld, its text: %s\n", msg.mtype,
msg.mtext);
return 0;
}
int main(int argc, char *argv[])
{
pid_t child;
int msg_queue, status;
key_t key;
char **cities = (char**) malloc(sizeof(*cities) * 3);
for (unsigned i = 0; i < 3; i++)
{
cities[i] = (char*) malloc(sizeof(*cities[i]) * 21);
}
strcpy(cities[0], "Berlin");
strcpy(cities[1], "London");
strcpy(cities[2], "Rome");
signal(SIGUSR1, handler);
key = ftok(argv[0], 2);
printf("The key: %d\n", key);
msg_queue = msgget(key, 0600 | IPC_CREAT);
if (msg_queue < 0)
{
perror("msgget");
return 1;
}
child = fork();
if (child > 0)
{
pid_t childPrime = fork();
if (childPrime == 0)
{
printf("childPrime commences..\n");
sleep(1);
kill(getppid(), SIGUSR1);
printf("childPrime teminates\n");
}
else
{
send(msg_queue, cities); // Parent sends a message.
pause();
wait(NULL);
// After terminating child process, the message queue is deleted.
//status = msgctl( uzenetsor, IPC_RMID, NULL );
if (status < 0)
perror("msgctl");
for (unsigned i = 0; i < 3; i++)
{
free(cities[i]);
}
free(cities);
printf("Parent terminates\n");
}
}
else if (child == 0)
{
printf("Child commences...\n");
sleep(1);
return receive(msg_queue);
// The child process receives a message.
printf("Child terminates\n");
}
else
{
perror("fork");
return 1;
}
return 0;
}