Register a name in the namespace and create a channel


#include <sys/iofunc.h>
#include <sys/dispatch.h>

name_attach_t * name_attach( dispatch_t * dpp,
                             const char * path,
                             unsigned flags );


NULL, or a dispatch handle returned by dispatch_create() or dispatch_create_channel() .
The path that you want to register under /dev/name/[local|global]/. This name shouldn't contain any .. characters or start with a leading slash /.
Flags that affect the function's behavior:
  • NAME_FLAG_ATTACH_GLOBAL — attach the name globally instead of locally.



Use the -l c option to qcc to link against this library. This library is usually included automatically.


The name_attach(), name_close() , name_detach() , and name_open() functions provide the basic pathname-to-server-connection mapping, without having to become a full resource manager.

If you've already created a dispatch structure, pass it in as the dpp. If you provide your own dpp, set flags to NAME_FLAG_DETACH_SAVEDPP when calling name_detach(); otherwise, your dpp is detached and destroyed automatically.

If you choose to pass a NULL as the dpp, name_attach() calls dispatch_create() and resmgr_attach() internally to create a channel, however, it doesn't set any channel flag by itself. The created channel will have the _NTO_CHF_DISCONNECT, _NTO_CHF_COID_DISCONNECT and _NTO_CHF_UNBLOCK flags set.

The name_attach() function puts the name path into the path namespace under /dev/name/[local|global]/ path . The name is attached locally by default, or globally when you set NAME_FLAG_ATTACH_GLOBAL in the flags. You can see attached names in /dev/name/local and /dev/name/global directories.

The application that calls name_attach() receives an _IO_CONNECT message when name_open() is called. The application has to handle this message properly with a reply of an EOK to allow name_open() connect.

If the receive buffer that the server provides isn't large enough to hold a pulse, then MsgReceive() returns -1 with errno set to EFAULT.


The name_attach() function returns a pointer to a name_attach_t structure that looks like this:

typedef struct _name_attach {
    dispatch_t* dpp;
    int         chid;
    int         mntid;
    int         zero[2];
} name_attach_t;

The members include:

The dispatch handle used in the creation of this connection.
The channel ID used for MsgReceive() directly.
the mount ID for this name.

The information that's generally required by a server using these services is the chid.


A pointer to a filled-in name_attach_t structure, or NULL if the call fails (errno is set).


An error occurred when the function tried to create a channel; see ChannelCreate() .
The specified path already exists.
Invalid arguments (i.e. a NULL or empty path, a path starts with a leading slash / or contains .. characters).
Not enough free memory to complete the operation.
A component of the pathname wasn't a directory entry.


#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/dispatch.h>

#define ATTACH_POINT "myname"

/* We specify the header as being at least a pulse */
typedef struct _pulse msg_header_t;

/* Our real data comes after the header */
typedef struct _my_data {
    msg_header_t hdr;
    int data;
} my_data_t;

/*** Server Side of the code ***/
int server() {
   name_attach_t *attach;
   my_data_t msg;
   int rcvid;

   /* Create a local name (/dev/name/local/...) */
   if ((attach = name_attach(NULL, ATTACH_POINT, 0)) == NULL) {
       return EXIT_FAILURE;

   /* Do your MsgReceive's here now with the chid */
   while (1) {
       rcvid = MsgReceive(attach->chid, &msg, sizeof(msg), NULL);

       if (rcvid == -1) {/* Error condition, exit */

       if (rcvid == 0) {/* Pulse received */
           switch (msg.hdr.code) {
           case _PULSE_CODE_DISCONNECT:
                * A client disconnected all its connections (called
                * name_close() for each name_open() of our name) or
                * terminated
           case _PULSE_CODE_UNBLOCK:
                * REPLY blocked client wants to unblock (was hit by
                * a signal or timed out).  It's up to you if you
                * reply now or later.
                * A pulse sent by one of your processes or a
                * from the kernel?

       /* name_open() sends a connect message, must EOK this */
       if (msg.hdr.type == _IO_CONNECT ) {
           MsgReply( rcvid, EOK, NULL, 0 );

       /* Some other QNX IO message was received; reject it */
       if (msg.hdr.type > _IO_BASE && msg.hdr.type <= _IO_MAX ) {
           MsgError( rcvid, ENOSYS );

       /* A message (presumable ours) received, handle */
       printf("Server receive %d \n",;
       MsgReply(rcvid, EOK, 0, 0);


   /* Remove the name from the space */
   name_detach(attach, 0);

   return EXIT_SUCCESS;

/*** Client Side of the code ***/
int client() {
    my_data_t msg;
    int server_coid;

    if ((server_coid = name_open(ATTACH_POINT, 0)) == -1) {
        return EXIT_FAILURE;

    /* We would have pre-defined data to stuff here */
    msg.hdr.type = 0x00;
    msg.hdr.subtype = 0x00;

    /* Do whatever work you wanted with server connection */
    for (; < 5; {
        printf("Client sending %d \n",;
        if (MsgSend(server_coid, &msg, sizeof(msg), NULL, 0) == -1) {

    /* Close the connection */
    return EXIT_SUCCESS;

int main(int argc, char **argv) {
    int ret;

    if (argc < 2) {
        printf("Usage %s -s | -c \n", argv[0]);
        ret = EXIT_FAILURE;
    else if (strcmp(argv[1], "-c") == 0) {
        printf("Running Client ... \n");
        ret = client();   /* see name_open() for this code */
    else if (strcmp(argv[1], "-s") == 0) {
        printf("Running Server ... \n");
        ret = server();   /* see name_attach() for this code */
    else {
        printf("Usage %s -s | -c \n", argv[0]);
        ret = EXIT_FAILURE;
    return ret;


QNX Neutrino

Cancellation point Yes
Interrupt handler No
Signal handler No
Thread Yes


As a server, you shouldn't assume that you're doing a MsgReceive() on a clean channel. In QNX Neutrino (and QNX 4), anyone can create a random message and send it to a process or a channel.

We recommend that you do the following to assure that you're playing safely with others in the system:

#include <sys/neutrino.h>

/* All of your messages should start with this header */
typedef struct _pulse msg_header_t;

/* Now your real data comes after this */
typedef struct _my_data {
        msg_header_t  hdr;
        int           data;
} my_data_t;


Contains a type/subtype field as the first 4 bytes. This allows you to identify data which isn't destined for your server.
Specifies the receive data structure. The structure must be large enough to contain at least a pulse (which conveniently starts with the type/subtype field of most normal messages), because you'll receive a disconnect pulse when clients are detached.