bofc manual pages




psmq_receivepsmq_timedreceivepsmq_timedreceive_ms - receive single message over psmq.  


#include <psmq.h>

int psmq_receive(struct psmq *psmq, struct psmq_msg *msg, unsigned *prio)
int psmq_timedreceive(struct psmq *psmq, struct psmq_msg *msg, unsigned *prio, struct timespec *tp)
int psmq_timedreceive_ms(struct psmq *psmq, struct psmq_msg *msg, unsigned *prio, size_t ms)
char * PSMQ_TOPIC(struct psmq_msg psmq)
void * PSMQ_PAYLOAD(struct psmq_msg psmq)  


Receive single control message or message that client has subscribed to. Functions will block calling thread until message is received. Message will be stored in user provided memory pointed by msg.

Message is stored in struct psmq_msg which definition is:

    struct psmq_msg {
        struct ctrl {
            char  cmd;
            unsigned char data;
        } ctrl;
        unsigned short paylen;
        char data[PSMQ_MSG_MAX];

ctrl.cmd defines type of received message. This can be one of:

Received message on previously subscribed topics.
Subscribe confirmation has been received.
Unsubscribe confirmation has been received.
Broker closed connection with the client.
Response from the broker for ioctl request. is a response status of received message. Or simply return code of a previous request. 0 is set when request was a success or errno when error occured. For example, when psmq_subscribe(3) has been sent, broker will reply with ctrl.cmd set to PSMQ_CTRL_CMD_SUBSCRIBE and set to 0 when subscribe has been successful or, for example EBADMSG when topic was not correct.

data contains both topic and payload data. Topic and payload can be extracted by using PSMQ_TOPIC() and PSMQ_PAYLOAD() macros and passing struct psmq_msg as argument. PSMQ_TOPIC() will return valid c-string with topic, while PSMQ_PAYLOAD() will return pointer where payload starts. Accessing pointer returned by PSMQ_PAYLOAD() is only valid when paylen is bigger than 0, otherwise you risk getting SIGSEGV from OS.

When is PSMQ_CTRL_CMD_IOCTL then data will not contain topic but first byte will be ioctl request number and all of the following bytes are ioctl specific. In general all of reponses from ioctl will require custom parsing. Check psmq_ioctl(3) for all possible ioctls.

paylen Length of payload part in data.

psmq_timedreceive(3) works same way as psmq_receive(3) but will block only until timeout tp occurs. Timeout is absolute time since Epoch when timeout should occur. If this function is called when timeout already occured (tp happens to be behind current time) and message is not available in queue, function will return immediately.

psmq_timedreceive_ms(3) works same way as psmq_timedreceive(3) but accepts relative timeout in form of ms. If message is not received in ms time from the moment function is called, then the function will return. If ms is set to 0 and message is not on the queue, function will return immediately.  


When message is received 0 is returned. On error -1 with appropriate errno set is returned.  


psmq or msg is NULL.
Subscribe queue is invalid inside passed psmq object. It is possible that psmq has not yet been initialized, or psmq_cleanup(3) has been called on it earlier, or psmq_init(3) failed.
The call was interrupted by a signal handler.

psmq_timedreceive(3) and psmq_timedreceive_ms(3) can also return:

The call timedout before a message could be transferred.


Example shows how to initialize, subscribe and receive data from psmq. Note: error checking has been ommited for clarity.

    #include <psmq.h>
    #include <stdio.h>

    int main(void)
        struct psmq psmq;
        int rpm;
        int i;

        /* initialize psmq object that will create /sub mqueue for
         * receiving data, and will connect to broker of name /brok.
         * Max items in queue is set to 10 */
        psmq_init(&psmq, "/brok", "/sub", 10);

        /* subscribe to receive revolution per minute information */
        psmq_subscribe(&psmq, "/can/+/rpm");

        for (i = 0; i != 10; ++i) {
            /* now we are ready to receive data. In this example we
             * simply print received rpm */
            struct psmq_msg msg;
            psmq_receive(&psmq, &msg, NULL);
            memcpy(&rpm, PSMQ_PAYLOAD(msg), sizeof(rpm));
            printf("topic: %s; rpm %d\n", PSMQ_TOPIC(msg), rpm);

        /* after work is finished, we need to deregister from broker to
         * make space in broker for another client */
        return 0;


Please, report all bugs to "Michał Łyszczek <>"  


psmqd(1), psmq-pub(1), psmq-sub(1), psmq_cleanup(3), psmq_init(3), psmq_publish(3), psmq_receive(3), psmq_subscribe(3), psmq_timedreceive(3), psmq_timedreceive_ms(3), psmq_unsubscribe(3), psmq_building(7), psmq_overview(7).

19 May 2021 (v9999)