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: