[Previous]
[Contents]
[Next]

qnx_vc_attach()

establish a virtual circuit between two processes

Synopsis:

#include <sys/vc.h>
pid_t qnx_vc_attach( nid_t nid,
                     pid_t pid,
                     unsigned length,
                     int flags );

Description:

The qnx_vc_attach() function attempts to establish a network link, called a virtual circuit, between your process on your local node, and the process pid on the remote node nid. A buffer of size length bytes is allocated on both the local and remote nodes, and flags is a bitfield that specifies options about the virtual circuit.

Once a virtual circuit is attached, the two programs may communicate using the kernel functions (for example, Send(), Receive(), and Reply()) as if they were on the same node.

A virtual process, or vid, is created on both ends to represent the other remote process. Each vid consumes one entry in the process manager's process table, like an ordinary process, and length bytes of memory as a message buffer. You may Send() or Reply() or Writemsg() more than length bytes on a vid, since the system automatically grows the vid buffers as memory permits.

If you specify zero or your node number for nid, a search for pid is conducted on your local node. If pid is currently a valid process ID on your local node, pid is returned, and no virtual circuit is created. If pid is not a currently valid process ID on your node, -1 is returned, and errno is set.

The argument flags is the virtual circuit option bitfield. The following options bits are defined in <sys/vc.h>:

0
A new virtual process and a new buffer are allocated on both ends.
_VC_AT_SHARE
If you have already attached a vid to pid on nid, the existing vid is returned to you after virtual circuit link counts on both ends have been incremented.

Note that, if you specify a bigger length than was specified by your previous qnx_vc_attach(), a bigger buffer is transparently allocated on both ends.

If you specify a pid on a nid that you don't already have a virtual circuit to, and request shared, a new vid is created on both ends, as if you hadn't requested shared.

This option is best used for reducing the use of process entries and memory when communicating with a passive remote manager like the file system.


Note: Don't use this option if both the local and remote processes asynchronously communicate on the virtual circuit. Also, in this circumstance, be sure to specify the maximum message size for length when the vid is attached - asynchronous communication on a vid should be avoided if you wish to automatically grow a vid buffer during a kernel call.

_VC_AT_REM_ZOMBIE
The remote vid will become a zombie process when the remote pid terminates.

Normally, virtual processes never become zombies. This option can be useful for learning the return code of a remote process, and is used by the shell for this purpose.

Note that a vid that's shared will either become a zombie process or not. This is set permanently for the life of that vid when it's first created.

So, if you wish to use the zombie option, don't use the shared option at the same time, in case you already have a vid to that same nid and pid, and didn't previously specify the zombie option.

You can free a virtual circuit using qnx_vc_detach(). This frees the vid's process entry and memory on both the local and remote node. Note that if you have shared vids, you must detach as many times as you attached to really get rid of the vid, and free up its process entry and buffer.

When a process dies, all of its virtual circuits are automatically detached.

Returns:

The virtual process id (vid) on your local node upon success. On failure, -1 is returned and errno is set.

Errors:

If any of the following conditions occurs, the qnx_vc_attach() function returns -1, and sets errno to the corresponding value:

EAGAIN
Process manager to net manager enqueuing failed.
EHOSTUNREACH
The destination node isn't in the net mapping, or a physical I/O error occurred while trying to communicate to the node.
EINVAL
The virtual circuit buffer was too big.
ENOLIC
Attempt to communicate to a node outside your current licensing capabilities.
ENOMEM
Couldn't allocate a buffer of size length bytes.
ENOVPE
No process entry available for virtual circuit.
ENOSYS
No network manager found.
ESRCH
pid doesn't exist, or may not be a vid or proxy.

Examples:

#include <stdio.h>
#include <errno.h>
#include <sys/vc.h>
#include <sys/kernel.h>

nid_t    nid;
pid_t    pid, vid1, vid2;
int    msg[5000];

/*
 * NOTE: the process manager ignores the data in
 *       the message if the message code is -1.
 */

void main()
  {
    nid = 2;

    pid = PROC_PID;

    /*
     *    set up a virtual circuit to the process manager
     *    on node 2
     */
    if( ( vid1 = qnx_vc_attach( nid, pid, 1000, 0 ) )
       == -1 ) {
      printf( "qnx_vc_attach() failed, errno = %d\n",
      errno );
    }

    /*
     *    send 1000 bytes, limit reply size to 10 bytes
     */
    msg[0] = -1;
    if( Send( vid1, msg, msg, 1000, 10 ) == -1 ) {
      printf( "Send() #1 failed, errno = %d\n", errno );
    }

    /*
     *    pretending that we have forgotten about vid1
     *    above, we set up another virtual circuit to the
     *    process manager on node 2.  We will reuse vid1
     *    above, and grow the vid buffer to 2000 bytes.
     */
    if( ( vid2 =
          qnx_vc_attach( nid, pid, 2000, _VC_AT_SHARE ) )
          == -1 ) {
      printf( "qnx_vc_attach() #2 failed, errno = %d\n",
        errno );
    }

    /* they should be the same! */
    printf( "vid1 = %d, vid2 = %d\n", vid1, vid2 );

    /*
     *    send 2000 bytes, limit reply to 150 bytes
     */
    msg[0] = -1;
    if( Send( vid2, msg, msg, 2000, 150 ) == -1 ) {
      printf( "Send() #2 failed, errno = %d\n", errno );
    }

    /*
     *    automatically grow our vid by sending 5000
     *    bytes.    limit reply to 5000 bytes.
     */
    msg[0] = -1;
    if( Send( vid2, msg, msg, 5000, 5000 ) == -1 ) {
      printf( "Send() #3 failed, errno = %d\n", errno );
    }
    qnx_vc_detach( vid1 );
    qnx_vc_detach( vid2 );
  }

Classification:

QNX

Safety:
Interrupt handler No
Signal handler Yes, but modifies errno
Thread Yes

See also:

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


[Previous]
[Contents]
[Next]