Question

I am using C language with GCC compiler on Linux. I have two processes, and I want to pass integer from one process to another i.e from external process to central process and than central process should print it. But my code is not working. Can anyone tell me how to correct it? Here is my code

central.c

#include<sys/types.h>
#include<sys/ipc.h>  
#include<sys/msg.h>
#include<stdio.h>

#define MsgKey 2345

typedef struct data_struct
{
    int  temp;
}data;

void main(void)
{
    data temp_msg;
    int msgqid;

if(msgqid=msgget(MsgKey, 0600 | IPC_CREAT)<0)
{
        printf("From Central Process: Msg queue failed");
}

msgrcv(msgqid,&temp_msg,sizeof(temp_msg),2,0);
printf("Value  = %d\n",temp_msg.temp);

printf("Central process exiting\n");
}

external.c

#include<sys/types.h> 
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>

#define MsgKey 2345

typedef struct data_struct
{  
    int  temp;
}data;

void main(void)
{
    data temp_msg;
    int msgqid;

        temp_msg.temp=5;

if(msgqid=msgget(MsgKey, 0600 | IPC_CREAT)<0)
{
        printf("From External Process: Msg queue failed");
}

if(msgsnd(msgqid,&temp_msg,sizeof(temp_msg),0)<0)
{
    printf("Error");
}
printf("External process exiting\n");
}

Than on terminal I typed

gcc -o central central.c
gcc -o external external.c
./central &
./external

I received this "External process exiting" and the external process terminates while central process keeps on running on the background.

Was it helpful?

Solution

From the POSIX documentation for msgsnd:

The application shall ensure that the argument msgp points to a user-defined buffer that contains first a field of type long specifying the type of the message, and then a data portion that holds the data bytes of the message. The structure below is an example of what this user-defined buffer might look like:

struct mymsg {
    long   mtype;       /* Message type. */
    char   mtext[1];    /* Message text. */
}

You're not following that, so your code can't work. Add an long field at the start of your structure, and set it to 2 since that's what your receiver is expecting as a message type.

Also move that structure definition to a header file so that you can share it between your two pieces of code rather than duplicate it.

 if(msgqid=msgget(MsgKey, 0600 | IPC_CREAT)<0)

Add parens around the assignment (in both pieces of code):

 if((msgqid=msgget(MsgKey, 0600 | IPC_CREAT)) < 0)

< and the other comparison operators have higher precedence than the assignment operator, so your code is incorrect without the parens - it assigns the result of the comparison to msgqid.

And finally, main returns an int, never void.

OTHER TIPS

The structure that you are passing to msgsnd() does not conform to the required format:

struct msgbuf {
    long mtype;
    ...
};

As such, the temp field is probably being interpreted as the message type, causing unexpected results.

My advice? Avoid POSIX message queues. If you need interprocess messaging, just use sockets. They're far simpler to work with, and are network transparent.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top