David Frickert
David Frickert

Reputation: 127

C - make msgrcv coexist with signals

I need some help with msgrcv... I need to be able to receive messages like this:

while(1){
    int status = msgrcv(qid, &msg, sizeof(msg.data), user_id,0 )
    if(status < 0) { perror("something wrong..."); exit(1); }
}

And also somewhere on the code:

void stuff_to_do(int signal){
   //   ....
}
//...
signal(SIGQUIT, stuff_to_do);

But I get a Interrupted System Call, probably because the signal kills the msgrcv or something like that. How can I solve this? Should i fork() and do the msgrcv in one process and do the stuff on the other process? Or is there a better way? Thanks for the help!

Upvotes: 0

Views: 907

Answers (1)

e0k
e0k

Reputation: 7161

Yes, if your process receives a signal during msgrcv(), it will be interrupted.

From the man pages on msgrcv():

The calling process catches a signal. In this case the system call fails with errno set to EINTR. (msgrcv() is never automatically restarted after being interrupted by a signal handler, regardless of the setting of the SA_RESTART flag when establishing a signal handler.)

Try to identify this failure condition and just restart msgrcv() with something like

while (1) {
    // Try to receive message
    errno = 0;
    int status = msgrcv(qid, &msg, sizeof(msg.data), user_id,0 )

    if (status < 0) {
        if (errno == EINTR) continue;  // try again

        // Something else went wrong
        perror("something wrong...");
        exit(1);
    }
}

Don't forget that you have to manually set errno = 0 before the operation you want to test.

This reminds me of a good answer that describes concurrency and simultaneity. It explains why you have to always use the approach of trying the operation, then check to see if it succeeded.


See also:

Upvotes: 1

Related Questions