From c94ef361924b8fa778a3ec5433cccd35fa12e9d7 Mon Sep 17 00:00:00 2001 From: Michał Łyszczek Date: Tue, 18 May 2021 20:39:08 +0200 Subject: lib/psmq.c: make sure valid errno is returned MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases, when we receive error from broker, OS will overwrite errno to 0 when mq_close() or mq_unlink() has succeeded leading to invalid errno being returned. Signed-off-by: Michał Łyszczek --- lib/psmq.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/psmq.c b/lib/psmq.c index 914d559..6db30a5 100644 --- a/lib/psmq.c +++ b/lib/psmq.c @@ -321,6 +321,7 @@ int psmq_init struct mq_attr mqa; /* mqueue attributes */ int ack; /* ACK from the broker after open */ size_t mqnamelen; /* length of mqname string */ + int saveerrno; /* saved errno value */ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ @@ -341,6 +342,7 @@ int psmq_init mqa.mq_maxmsg = maxmsg; psmq->qsub = (mqd_t)-1; psmq->qpub = (mqd_t)-1; + ack = 0; /* if staled queue exist, remove it, so it * doesn't do weird stuff */ @@ -418,28 +420,36 @@ int psmq_init break; } - /* broker will return either 0 or errno to - * indicate what went wrong on his side, if - * ack is 0, broker will send file descriptor - * to use when communicating with him. */ - if (ack != 0) - { - if (ack > 0) - errno = ack; - - goto error; - } - /* ack received and fd is valid, * we are victorious */ - return 0; + if (ack == 0) + return 0; error: + /* broker will return either 0 or errno to + * indicate what went wrong on his side, if + * ack is 0, broker will send file descriptor + * to use when communicating with him. + * + * if() is here, because we can get here when + * psmq_publish_msg() fails, in which case ack + * will be 0 and then we won't want to set errno + * as it's already set by psmq_publish_msg() */ + if (ack > 0) + errno = ack; + + /* some OSes like to overwrite errno with 0 when + * syscalls have succeded. It's unusuall but can + * happen (like on Solaris) */ + saveerrno = errno; + mq_close(psmq->qpub); mq_close(psmq->qsub); mq_unlink(mqname); psmq->qpub = (mqd_t)-1; psmq->qsub = (mqd_t)-1; + + errno = saveerrno; return -1; } -- cgit v1.2.3-8-gadcc