The default functions make use of helper functions—these functions can't be placed directly into the connect or I/O jump tables, but they do perform the bulk of the work.
Here's the source for the two functions iofunc_chmod_default() and iofunc_stat_default():
int
iofunc_chmod_default (resmgr_context_t *ctp, io_chmod_t *msg,
iofunc_ocb_t *ocb)
{
return (iofunc_chmod (ctp, msg, ocb, ocb -> attr));
}
int iofunc_stat_default( resmgr_context_t *ctp, io_stat_t *msg,
iofunc_ocb_t *ocb)
{
int status;
/* Update stale time fields (ctime, mtime, atime) this OCB.
*/
(void)iofunc_time_update(ocb->attr);
if ((status = iofunc_stat(ctp, ocb->attr, &msg->o)) != EOK)
return(status);
return _RESMGR_PTR(ctp, &msg->o, sizeof msg->o);
}
Notice how the iofunc_chmod() handler performs all the work for the iofunc_chmod_default() default handler. This is typical for the simple functions.
The more interesting case is the iofunc_stat_default() default handler, which calls two helper routines. First it calls iofunc_time_update() to ensure that all of the time fields (atime, ctime and mtime) are up to date. Then it calls iofunc_stat(), which builds the reply. Finally, the default function builds a pointer in the ctp structure and returns -1, to indicate to the resource manager library that it should return one part from the ctp->iov structure to the client.
The most complicated handling is done by the iofunc_open_default() handler:
int
iofunc_open_default (resmgr_context_t *ctp, io_open_t *msg,
iofunc_attr_t *attr, void *extra)
{
int status;
iofunc_attr_lock (attr);
if ((status = iofunc_open (ctp, msg, attr, 0, 0)) != EOK) {
iofunc_attr_unlock (attr);
return (status);
}
if ((status = iofunc_ocb_attach (ctp, msg, 0, attr, 0))
!= EOK) {
iofunc_attr_unlock (attr);
return (status);
}
iofunc_attr_unlock (attr);
return (EOK);
}
This handler calls four helper functions: