The _IO_OPEN message for filesystems
pathID = resmgr_attach(
dpp,
&resmgr_attr,
"/sample_fsys", /* mountpoint */
_FTYPE_ANY,
_RESMGR_FLAG_DIR, /* it's a directory */
&connect_funcs,
&io_funcs,
&attr);
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.
- 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 C Library Reference page for the iofunc_open() for information detailing the steps needed for this level of checking.)
- We must determine the appropriate attribute structure to bind to the client's open() request based on
the pathname, and bind it to the OCB with iofunc_open_default()
or resmgr_open_bind().
Generally this will be a different attribute structure than the one passed to the io_open handler,
unless the path is empty (i.e.,
path[0] == '\0'
).