0

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;
}
Bodo
  • 9,287
  • 1
  • 13
  • 29
curiousMind_85
  • 167
  • 1
  • 8
  • 1
    Please [edit] your question and add more details. What (example) output would you expect, what do you actually get. I get this sequence of output: `The key: 33623116` `Child commences...` `childPrime commences..` `childPrime teminates` `Code of received message: 5, its text: Berlin` `Signal with ID 10 has arrived`. The name of the city and the order of the lines vary. – Bodo May 19 '22 at 11:37
  • I've just made an edit. – curiousMind_85 May 19 '22 at 11:41
  • 1
    I fixed the indentation of your code. Add an example of the expected output and copy&paste the actual output. The line `printf("Child terminates\n");` is unreachable after a `return` statement. I get the output line `Parent terminates`. I overlooked it because I compiled your program with a memory sanitizer which prints messages about memory leaks before this line. – Bodo May 19 '22 at 12:13
  • 1
    Call `srand()` once only. – Jonathan Leffler May 19 '22 at 12:24
  • On the server I am working on the city name now gets printed. It only emerged after I removed the return from the block of child. Now, however the prompt does not return. – curiousMind_85 May 19 '22 at 12:42
  • It looks like the problem ceased to exist. Thank you for your help! :) – curiousMind_85 May 19 '22 at 12:47

0 Answers0