This is where things get interesting. Our io_read() function gets called to handle three things:
The first two operate on a file, and the last operates on a directory. So that's the first decision point in our new io_read() handler:
static int
io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb)
{
int sts;
// use the helper function to decide if valid
if ((sts = iofunc_read_verify (ctp, msg, &ocb -> base, NULL)) != EOK) {
return (sts);
}
// decide if we should perform the "file" or "dir" read
if (S_ISDIR (ocb -> base.attr -> base.mode)) {
return (io_read_dir (ctp, msg, ocb));
} else if (S_ISREG (ocb -> base.attr -> base.mode)) {
return (io_read_file (ctp, msg, ocb));
} else {
return (EBADF);
}
}
By looking at the attributes structure's mode field, we can tell if the request is for a file or a directory. After all, we set this bit ourselves when we initialized the attributes structures (the S_IFDIR and S_IFREG values).