Updated: May 06, 2022

Attach a path to the pathname space


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

int resmgr_attach (
       dispatch_t *dpp,
       resmgr_attr_t *attr,
       const char *path, 
       enum _file_type file_type,
       unsigned flags, 
       const resmgr_connect_funcs_t *connect_funcs,
       const resmgr_io_funcs_t *io_funcs,
       RESMGR_HANDLE_T *handle );
Note: In order to correctly define RESMGR_HANDLE_T, #include <sys/iofunc.h> before <sys/resmgr.h>.


A dispatch handle created by a successful call to dispatch_create().
A pointer to a resmgr_attr_t structure (see below) that defines attributes for the resource manager, or NULL to use the default attributes.
NULL, or the path that you want to attach the resource manager to; see below.
The file type; usually, _FTYPE_ANY. For more information, see File types below.
Flags that control the pathname resolution:

For more information, see The flags argument,” below.

A pointer to the resmgr_connect_funcs_t structure that defines the POSIX-level connect functions. The library stores this pointer for future use.
A pointer to the resmgr_io_funcs_t structure that defines the POSIX-level I/O functions. The library stores this pointer for future use.
A pointer to an arbitrary structure that you want to associate with the pathname you're attaching. For most resource managers, this is an iofunc_attr_t structure. The library stores this pointer for future use.



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


The resmgr_attach() function puts the path into the general pathname space and binds requests on this path to the dispatch handle dpp. You usually provide an absolute path; if you provide a path that doesn't start with a slash, it's considered to be relative to the current working directory.

The function does three main things:
  1. On the first resmgr_attach() call for any dispatch framework, it sets up the framework to handle resource manager operations.
  2. It allocates a unique link ID and associates the connect_funcs, io_funcs, and handle pointers with this link ID.
  3. It registers the pathname and link ID with the process manager.
If path is NULL, only the first step will be done, unless RESMGR_FLAG_ATTACH_LOCAL is set in attr.flags or _RESMGR_FLAG_FTYPEONLY is set in flags (see below). This could, for example, be used to prepare for a later name registration when a removable device is plugged in.
  • Your process needs certain abilities enabled:
    • PROCMGR_AID_PATHSPACE, to add a name to the pathname space

    For more information, see procmgr_ability().

  • Once you've called dispatch_context_alloc(), don't call message_attach() or resmgr_attach() specifying a larger maximum message size or a larger number of message parts for the same dispatch handle. In QNX Neutrino 7.0 or later, these functions indicate an error of EINVAL if this happens.
  • After calling resmgr_attach(), any child process created with fork() that does not exec() can't be a resource manager.

File types

File types are used with the _RESMGR_FLAG_FTYPEONLY flag for special services that have their own associated open function to ensure they receive only those open requests targeted for them. For example, the mqueue manager sets file_type to _FTYPE_MQUEUE, and mq_open() requests a pathname match of the same type.

When matching an open request to a registered path's file type, an exact match will always reach the server. If the server sets _RESMGR_FLAG_FTYPEONLY, then only an exact match will reach it. Otherwise, a request of _FTYPE_ANY will reach the server if it has registered any file type. If the server registers a file type of _FTYPE_ALL, which is done by setting the _RESMGR_FLAG_FTYPEALL flag, then requests of all file types will reach the server.

Note: If a server specifies _RESMGR_FLAG_FTYPEONLY and _RESMGR_FLAG_FTYPEALL, no requests will reach it because the first flag allows for exact matches only and no client request is ever issued with a file type of _FTYPE_ALL.

The following table shows some of the different client-request function types and the types of pathnames they will match if the server has not set _RESMGR_FLAG_FTYPEALL:

Function: file_type: Matches pathname of type:
open() _FTYPE_ANY All types

Using POSIX functions

If you want to use the POSIX functions, we've provided you with the POSIX layer; to fill your connect and I/O functions tables with the default handler functions supplied by the POSIX layer library, call iofunc_func_init(). You can then override the defaults placed in the structures with your own handlers.

Note: The resmgr_attach() function copies the pointers to the resmgr_connect_funcs_t and resmgr_io_funcs_t structures, not the structures themselves. You should allocate the structures, declare them to be static, or make them global variables. If your resource manager is for more than one device with different handlers, create separate structures that define the handlers.

In the most general case, the last argument, handle is an arbitrary structure that you wish to have associated with the pathname you're attaching. Practically, however, we recommend that it contain the POSIX layer's well defined attributes structure, iofunc_attr_t, because this lets you use the POSIX-layer default library. You can extend the data that's contained in the attributes structure to contain any device-specific data that you may require. This is commonly done, and is described in the POSIX-Layer Data Structures chapter of Writing a Resource Manager.

Note: The resmgr_attach() function copies the pointers to the handle structure, not the structure itself. You should allocate the structure, declare it to be static, or make it a global variable. If your resource manager is for more than one device with different handles, create separate structures for each handle.

In order to use the POSIX layer default library, the attributes structure must be bound into the Open Control Block, and you must use the POSIX layer's iofunc_ocb_t OCB. This is described in the documentation for resmgr_open_bind(), as well as in the above reference.

resmgr_attr_t structure

You can specify attributes such as the maximum message size, number of parts (number of IOVs in context), and flags in the attr structure. The resmgr_attr_t structure looks like this:

typedef struct _resmgr_attr {
   unsigned      flags;
   unsigned      nparts_max;
   size_t        msg_max_size;
   int           (*other_func) ( resmgr_context_t *, void *msg );
   unsigned      reserved[4];
} resmgr_attr_t;

The members include:

Flags that affect the behavior of the resource manager interface; 0, or a combination of the following bits (defined in <sys/dispatch.h>):
  • RESMGR_FLAG_ATTACH_LOCAL — set up the resource manager, but don't register its path with procnto. That is, perform the first two of the three steps listed above. In this case the path parameter is ignored and, hence, may be NULL.
  • RESMGR_FLAG_CROSS_ENDIAN — the server handles cross-endian support. The framework handles all necessary conversions on the server's side; the client doesn't have to do anything.
  • RESMGR_FLAG_NO_DEFAULT_FUNC — not implemented.
  • RESMGR_FLAG_RCM (QNX Neutrino 6.6 or later) — automatically adopt the client's resource constraint mode when handling a request. For more information, see Resource constraint thresholds in the Processes chapter of the QNX Neutrino Programmer's Guide.
Note: Don't confuse these flags with the ones you pass in the flags argument to resmgr_attach(). The names of these flags don't start with an underscore (_).
The number of components to allocate for the IOV array. If you specify 0, the resource manager library bumps the value to the minimum usable by the library itself.
The minimum amount of room to reserve for receiving a message that's allocated in resmgr_context_alloc(). If the value is too low, or you specify it as 0, resmgr_attach() picks a value that's usable.
A pointer to a function that's called if the resource manager receives an I/O message that it didn't successfully handle. Only the first other_func registered for any particular dpp is used; any later attempts to register an other_func are silently ignored.

The flags argument

The flags argument to resmgr_attach() specifies additional information to control the pathname resolution.

Note: Don't confuse these flags with the ones you set in the flags member of the resmgr_attr_t structure. The names of these flags start with an underscore (_).

The flags (defined in <sys/resmgr.h>) include at least the following bits:

Force the path to be resolved after others with the same pathname at the same mountpoint.
Force the path to be resolved before others with the same pathname at the same mountpoint.
Note: If multiple registrations are made with _RESMGR_FLAG_BEFORE or _RESMGR_FLAG_AFTER, then all BEFORE registrations are resolved first in FIFO order, followed by the non-flagged registrations in LIFO order, and then all AFTER registrations in LIFO order (i.e., the first BEFORE registered is resolved first, and the first AFTER registered is resolved last).
The manager will use resmgr_detach_ctp() on the path.
Treat the pathname as a directory and allow the resolving of longer pathnames. The _IO_CONNECT message contains the pathname passed to the client open() with the matching prefix stripped off. Without this flag, the pathname is treated as a simple file requiring an exact match.
Attached path Opened path _RESMGR_FLAG_DIR set _RESMGR_FLAG_DIR clear
/a/b /a/b Match "" Match ""
/a/b /a/b/c Match c No match
/a/b /a/b/c/d Match c/d No match
/a/b /a/bc No match No match

You can't attach a directory pathname that contains, as a subset, an existing file pathname. Likewise, you can't attach a file pathname that's a subset of an existing directory pathname.

Existing path New path New path allowed?
Directory /a/b Directory /a Yes
Directory /a/b Directory /a/b/c Yes
File /a/b Directory /a Yes
File /a/b Directory /a/b/c No; the directory is beneath a file
Directory /a/b File /a No; the directory is beneath a file
Directory /a/b File /a/b/c Yes
File /a/b File /a Yes
File /a/b File /a/b/c Yes
Handle requests for all file types. Ignores the specified file type, instead registering for a file type of _FTYPE_ALL.
Handle only requests for the specific file type indicated. The pathname must be NULL but the resulting registration is at "/" in the pathname space.
Don't resolve paths to mountpoints on a path shorter than this (i.e., find the longest match against all pathnames attached).
Allow requests to resolve back to this server; in other words, allow the resource manager to open a path to itself.
Be very careful if you set _RESMGR_FLAG_SELF because it's possible for a deadlock to occur. For more information, see Robust implementations with Send/Receive/Reply in the Interprocess Communication (IPC) chapter of the System Architecture guide.


A unique link ID associated with this attach, or -1 on failure (errno is set).

The returned ID is needed to detach the pathname at a later time using resmgr_detach(). The ID is also passed to all connect and I/O message handlers in the resource-manager context structure (ctp) created by resmgr_context_alloc().


(QNX Neutrino 7.0 or later) One of the following occurred:
  • Security policies are in use and there is no rule to permit the use of that path.
  • The process is sandboxed and the path is denied.
An internal resource wasn't available.
One of the following occurred:
  • (QNX Neutrino 7.0 or later) You've already called dispatch_context_alloc(), and you've now tried to increase the maximum message size or the number of message parts.
  • (QNX Neutrino 7.1 or later) You've already called pulse_attach() for _PULSE_CODE_UNBLOCK or _PULSE_CODE_DISCONNECT on this dispatch handle (dpp).
  • (QNX Neutrino 7.1 or later) You've already called dispatch_context_alloc() for a dpp with DISPATCH_FLAG_NOLOCK set, and you've now tried to do a first resmgr_attach().
There isn't enough free memory to complete the operation.
A component of the pathname wasn't a directory entry.
The calling process doesn't have the required permission; see procmgr_ability().


Here's an example of a simple single-threaded resource manager:

#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>

static resmgr_connect_funcs_t    connect_funcs;
static resmgr_io_funcs_t         io_funcs;
static iofunc_attr_t             attr;

int main(int argc, char **argv)
    dispatch_t           *dpp;
    resmgr_attr_t        resmgr_attr;
    resmgr_context_t     *ctp;
    int                  id;

    /* initialize dispatch interface */
    if ( (dpp = dispatch_create()) == NULL ) {
       fprintf( stderr, "%s: Unable to allocate \
                dispatch handle.\n", argv[0] );
       return EXIT_FAILURE;

    /* initialize resource manager attributes */
    memset( &resmgr_attr, 0, sizeof resmgr_attr );
    resmgr_attr.nparts_max = 1;
    resmgr_attr.msg_max_size = 2048;

    /* initialize functions for handling messages */
    iofunc_func_init( _RESMGR_CONNECT_NFUNCS, &connect_funcs,
                      _RESMGR_IO_NFUNCS, &io_funcs );

    /* initialize attribute structure */
    iofunc_attr_init( &attr, S_IFNAM | 0666, 0, 0 );

    /* attach our device name (passing in the POSIX defaults 
       from the iofunc_func_init and iofunc_attr_init functions) 
    if ( (id = resmgr_attach
          ( dpp, &resmgr_attr, "/dev/mynull", _FTYPE_ANY, 0,
          &connect_funcs, &io_funcs, &attr)) == -1 ) {
        fprintf( stderr, "%s: Unable to attach name.\n", \
                 argv[0] );
        return EXIT_FAILURE;

    /* allocate a context structure */
    ctp = resmgr_context_alloc( dpp );

    /* start the resource manager message loop */
    while (1) {
        if ( (ctp = resmgr_block( ctp )) == NULL ) {
           fprintf(stderr, "block error\n");
           return EXIT_FAILURE;

For more examples using the dispatch interface, see dispatch_create(), message_attach(), and thread_pool_create(). For more information on writing a resource manager, see Writing a Resource Manager


QNX Neutrino

Cancellation point Yes
Interrupt handler No
Signal handler No
Thread Yes