Once we've specified a mountpoint, it would then be up to the resource manager to determine a suitable response to an open request. Let's assume that we've defined a mountpoint of /sample_fsys for our resource manager:
pathID = resmgr_attach (dpp, &resmgr_attr, "/sample_fsys", /* mountpoint */ _FTYPE_ANY, _RESMGR_FLAG_DIR, /* it's a directory */ &connect_funcs, &io_funcs, &attr);
Now when the client performs a call like this:
fopen ("/sample_fsys/spud", "r");
we receive an _IO_CONNECT message, and our io_open handler will be called. Since we haven't yet looked at the _IO_CONNECT message in depth, let's take a look now:
struct _io_connect { unsigned short type; unsigned short subtype; /* _IO_CONNECT_* */ unsigned long file_type; /* _FTYPE_* in sys/ftype.h */ unsigned short reply_max; unsigned short entry_max; unsigned long key; unsigned long handle; unsigned long ioflag; /* O_* in fcntl.h, _IO_FLAG_* */ unsigned long mode; /* S_IF* in sys/stat.h */ unsigned short sflag; /* SH_* in share.h */ unsigned short access; /* S_I in sys/stat.h */ unsigned short zero; unsigned short path_len; unsigned char eflag; /* _IO_CONNECT_EFLAG_* */ unsigned char extra_type; /* _IO_EXTRA_* */ unsigned short extra_len; unsigned char path[1]; /* path_len, null, extra_len */ };
Looking at the relevant fields, we see ioflag, mode, sflag, and access, which tell us how the resource was opened.
The path_len parameter tells us how many bytes the pathname takes; the actual pathname appears in the path parameter. Note that the pathname that appears is not /sample_fsys/spud, as you might expect, but instead is just spud—the message contains only the pathname relative to the resource manager's mountpoint. This simplifies coding because you don't have to skip past the mountpoint name each time, the code doesn't have to know what the mountpoint is, and the messages will be a little bit shorter.
Note also that the pathname will never have relative (. and ..) path components, nor redundant slashes (e.g., spud//stuff) in it—these are all resolved and removed by the time the message is sent to the resource manager.
When writing filesystem resource managers, we encounter additional complexity when dealing with the pathnames. For verification of access, we need to break apart the passed pathname and check each component. You can use strtok() and friends to break apart the string, and then there's iofunc_check_access(), a convenient iofunc-layer call that performs the access verification of pathname components leading up to the target. (See the QNX Neutrino C Library Reference page for the iofunc_open() for information detailing the steps needed for this level of checking.)