Javier Fuentes
Javier Fuentes

Reputation: 43

why does msgrcv() sets msqid to 0?

I have a program in c which is supposed to send and receive ipc messages through msgq.

The problem I have is that when I run msgrcv() it sets my global int msqid to 0. And of course I need it at other methods, like in a signal handler.

here is some code:

/* all the includes and some variables*/
#include "msg.h" // include the one I made
int msgQ; // global int

int main(int argc, char *argv[])
{
    key = ftok("progfile", 65);
    msgQ = msgget(key, 0666 | IPC_CREAT);
    printf("msg queue id: %d \n", msgQ);

    start_tik_tok(); // setting up the timer and the signal handler
    /* irrelevant code */

    void read_msgs(msgQ);
}

void read_msgs(int msgQid)
{
    while (1)
    {
        printf("before the read local:%d goval:%d\n", msgQid, msgQ);
        int ret = msgrcv(msgQid, &message, sizeof(message), 1, 0);
        printf("after the read local:%d global :%d\n", msgQid, msgQ);
        if (ret == -1)
            /* error handling */

        switch (message.action_type)
        {
            /* mesage handling */
        }
}

void signal_handler(int signo)
{
    /*I need the global int here to send some messages */
}

void start_tik_tok()
{
    //timer interval for setitimer function
    struct itimerval timer;
    timer.it_interval.tv_sec = 1; //every 1 seconds
    timer.it_interval.tv_usec = 0;
    timer.it_value.tv_sec = 1; //start in 1 seconds
    timer.it_value.tv_usec = 0;

    //action for the signal
    struct sigaction new_sa;
    memset(&new_sa, 0, sizeof(new_sa));
    new_sa.sa_handler = &signal_handler;

    sigaction(SIGALRM, &new_sa, NULL);
    setitimer(ITIMER_REAL, &timer, NULL);
}

the msg.h file:

#include <sys/msg.h>

struct msg_buff{
    long mesg_type; //reciver
    int sender; //sender
    char action_type;
    char time_tiks; //time in tiks
} message;

output:

msg queue id: 45416448

before the read local:45416448 global:45416448

after the read local:45416448 global:0

...

you can see that after I run msgrcv(), the value of msgQ turns to 0, even though I'm using a variable to pass the value to the method read_msgs().

Upvotes: 1

Views: 629

Answers (2)

Javier Fuentes
Javier Fuentes

Reputation: 43

I found the solution, I'm not sure why is that but it solved it.

I just initialized the int from the beginning.

changed:

int msgQ; // global int

for:

int msgQ = 0; // global int

Upvotes: 0

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215193

The msgrcv function takes a pointer to a structure that starts with a "header" of type long, followed by the message data. The third argument to msgrcv, msgsz, is the size of the message data body, not including the long that's the header. So you should pass something like sizeof message - sizeof(long). By passing sizeof message, you're asking it to overflow the buffer sizeof(long) bytes, and this is clobbering some other global variable.

Upvotes: 2

Related Questions