Re: Re: Kernel module: return a number from a device

From: Rocky Hotas <rockyhotas_at_tilde.team>
Date: Tue, 09 Apr 2024 16:11:34 UTC
On apr 07 12:50, Dag-Erling Smørgrav wrote:

[...]
>
> Furthermore, this won't only return one byte; rather, it will return one
> byte _at a time_, very inefficiently.  This is why cat appears to hang.
> To truly only return one byte, you need to look at uio->uio_offset and
> return 0 without calling uiomove(), signaling EOF, if it is non-zero.
>
> In summary, you should write rolld_read() as:
>
>         uint8_t roll = arc4random() % d_size;
>         if (uio->uio_offset > 0)
>                 return (0);
>         return (uiomove(&roll, 1, uio));

A massive thank you for all your suggestions, which were very clarifying
about the way `uio' data can be used.

> You can also use uiomove_frombuf(), which will take care of that check
> for you.  It's a bit overkill when you're only writing a single byte,
> but if you wanted to output text instead of binary, you could use this:
>
>         char roll[2];
>         roll[0] = '0' + arc4random() % d_size;
>         roll[1] = '\n';
>         return (uiomove_frombuf(roll, sizeof(roll), uio));

Yes, I guess this is probably the most efficient way to perform this
operation.

If anyone moving the first steps into this topic and into uio(9) is
interested, here are:

1) a repository with three versions of this same module:

 <https://github.com/rockyhotas/freebsd_tests/tree/main/kernel_modules>

2) a blog post with some comments about them:

 <https://rockyhotas.github.io/freebsd,/kernel,/modules/2024/04/08/freebsd-random-number-module.html>

Rocky