aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Łyszczek <michal.lyszczek@bofc.pl>2021-05-18 20:39:08 +0200
committerMichał Łyszczek <michal.lyszczek@bofc.pl>2021-05-18 20:39:08 +0200
commitc94ef361924b8fa778a3ec5433cccd35fa12e9d7 (patch)
tree20dfbcda3579a8300de9be9fea075195d99b9257
parent1b9c7922f14557c2fac78f9b7292eef4f5a1df73 (diff)
downloadpsmq-c94ef361924b8fa778a3ec5433cccd35fa12e9d7.tar.gz
psmq-c94ef361924b8fa778a3ec5433cccd35fa12e9d7.tar.bz2
psmq-c94ef361924b8fa778a3ec5433cccd35fa12e9d7.zip
lib/psmq.c: make sure valid errno is returned
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 <michal.lyszczek@bofc.pl>
-rw-r--r--lib/psmq.c36
1 files 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;
}