diff options
author | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2021-05-18 20:39:08 +0200 |
---|---|---|
committer | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2021-05-18 20:39:08 +0200 |
commit | c94ef361924b8fa778a3ec5433cccd35fa12e9d7 (patch) | |
tree | 20dfbcda3579a8300de9be9fea075195d99b9257 | |
parent | 1b9c7922f14557c2fac78f9b7292eef4f5a1df73 (diff) | |
download | psmq-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.c | 36 |
1 files changed, 23 insertions, 13 deletions
@@ -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; } |