In the my_read() function, to decide what kind of processing we needed to do, we looked at the attribute structure's mode member. If the S_ISDIR() macro says that it's a directory, we call my_read_dir(); if the S_ISREG() macro says that it's a file, we call my_read_file(). (For details about these macros, see the entry for stat() in the QNX Neutrino C Library Reference.) Note that if we can't tell what it is, we return EBADF; this indicates to the client that something bad happened.

The code here doesn't know anything about our special devices, nor does it care; it simply makes a decision based on standard, well-known data.

static int
my_read (resmgr_context_t *ctp, io_read_t *msg, 
         iofunc_ocb_t *ocb)
    int     sts;

    // use the helper function to decide if valid
    if ((sts = iofunc_read_verify (ctp, msg, ocb, 
                                   NULL)) != EOK) {
        return (sts);

    // decide if we should perform the "file" or "dir" read
    if (S_ISDIR (ocb -> attr -> mode)) {
        return (my_read_dir (ctp, msg, ocb));
    } else if (S_ISREG (ocb -> attr -> mode)) {
        return (my_read_file (ctp, msg, ocb));
    } else {
        return (EBADF);