[Previous]
[Contents]
[Next]

Writemsgmx()

write a message to a reply message buffer

Synopsis:

#include <sys/kernel.h>
#include <sys/sendmx.h>
unsigned Writemsgmx( pid_t pid,
                     unsigned offset,
                     unsigned parts,
                     struct _mxfer_entry *msgmx );

Description:

The kernel function Writemsgmx() writes a message, taken from the array of message buffers pointed to by msgmx, to the reply message buffer of the process identified by pid. The number of elements in this array is given by nparts, which must not exceed _QNX_MXTAB_LEN (defined in <limits.h>). The size of the message is the sum of the sizes of each buffer. The offset allows you to write data to the senders reply message buffer starting at any point. The data transfer occurs immediately, and the writing task doesn't block. The state of the process pid isn't changed. You must call Reply() or Replymx() to READY the sender and complete the message exchange.

The process pid must have sent a message that was received and not yet replied to. It must be in the REPLY BLOCKED state.

If you attempt to write past the end of the senders reply buffer then Writemsg() returns fewer bytes than was specified in the sum of the buffer lengths in the _mxfer_entry list provided.

This function is often used in one of two situations:

  1. You're unable to build the entire reply at one time, and rather than buffer all the data, you write it into the destination process's waiting-reply-message buffer.
  2. You receive messages that are larger than your buffer space. Perhaps you're an agent in the middle of two processes and simply filter the data and pass it on. You can use Readmsg() to read the message in small amounts and then use Writemsg() or Writemsgmx() for writing messages in small amounts.

When you are through using Writemsgmx() you must use Reply() or Replymx() to ready the REPLY BLOCKED process and complete the message exchange. The reply doesn't need to contain any data. If it does, it's always written at offset zero in the destination process's message buffer.

A single call to Reply()/Replymx() is always more efficient than calls to Writemsg()/Writemsgmx() followed by a call to Reply()/Replymx().


Note: Avoid stuffing each _mxfer_entry directly. Instead use the _setmx() macro to stuff each entry. This will make your code portable across 16- and 32-bit platforms.

Returns:

The number of bytes written. On error, a -1 is returned, and errno is set.

Errors:

EAGAIN
No more Process Manager to Network Manager queue packets available.
EFAULT
In order to complete the message exchange, the current process would have incurred a segment violation. You need to make your buffer(s) larger, or limit the number of bytes allowed in the transfer.
EINTR
Call interrupted by a signal.
EINVAL
The virtual circuit buffer cant be grown due to an invalid message length.
ENOMEM
The virtual circuit buffer cant be grown because no memory is available.
ESRCH
The process pid doesn't exist.

Examples:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/kernel.h>
#include <sys/sendmx.h>

unsigned msg[3];

void main()
  {
    pid_t child, pid;
    struct _mxfer_entry mx[2];

    if( child = fork() )
      {
      Send( child, msg, msg, sizeof( msg ),
        sizeof( msg ) );
      printf( "Send returned %d %d %d.\n",
          msg[0], msg[1], msg[2] );
      }
    else
      {
      pid = Receive( 0, msg, sizeof( msg ) );
      msg[1] = 2;
      _setmx( &mx[0], &msg[1], sizeof( msg[1] ) );
      msg[2] = 3;
      _setmx( &mx[1], &msg[2], sizeof( msg[2] ) );
      Writemsgmx( pid, sizeof( msg[0] ), 2, mx );
      msg[0] = 1;
      Reply( pid, msg, sizeof( msg[0] ) );
      }

    exit( 0 );
  }

produces the output:

Send returned 1 2 3.

Classification:

QNX

Safety:
Interrupt handler No
Signal handler Yes
Thread Yes

Caveats:

Writemsgmx() is a macro.

See also:

Creceive(), Creceivemx(), errno, Receive(), Receivemx(), Reply(), Replymx(), Readmsg(), Readmsgmx(), Send(), Sendfd(), Sendfdmx(), Sendmx(), Trigger(), Writemsg()


[Previous]
[Contents]
[Next]