Reputation: 127
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
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