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).