Subject: O_NONBLOCK in a character device driver
To: None <tech-kern@NetBSD.ORG>
From: None <explorer@flame.org>
List: tech-kern
Date: 08/15/1997 08:48:39
I'm having some problems using O_NONBLOCK in a character device
driver.  It seems that the fcntl(fd, F_SETFL, O_NONBLOCK) call
returns 0 for no error, but the flags are not being passed to
the read routine correctly.

If I open the device and perform a read on it, I get something
like this:

Read of 32 requested, flags 0x00000000

from my code.  If I set non-blocking, I get this:

Read of 32 requested, flags 0x00000010

The problem is, O_NONBLOCK is defined to be 0x00000004, which most certainly
is not 0x10.

So, what is broken?

Here are the relevant parts of the ioctl and read functions of my driver.

int
rndread(dev, uio, ioflag)
        dev_t dev;
        struct uio *uio;
        int ioflag;
{
        int             ret;
        u_int32_t       nread;
        int             n;
        u_int8_t        buf[RND_TEMP_BUFFER_SIZE];
        u_int32_t       mode;

        if (rnd_ready != 1)
                return (ENXIO);

#ifdef RND_DEBUG_READ
        printf("Random:  Read of %d requested, flags 0x%08x\n",
               uio->uio_resid, ioflag);

...


int
rndioctl(dev, cmd, addr, flag, p)
        dev_t dev;
        u_long cmd;
        caddr_t addr;
        int flag;
        struct proc *p;
{
        int                      ret;
        rndsource_element_t     *rse;
        rndstat_t               *rst;
        u_int32_t                count;
        u_int32_t                start;
        
        if (rnd_ready != 1)
                return (ENXIO);

        ret = 0;

        switch (cmd) {
          /*
           * handled in upper layer...  why do we even get this?
           */
        case FIONBIO:
                break;
...
        }

        return ret;
}