The io_open() function

static int
io_open (resmgr_context_t *ctp, io_open_t *msg,
         RESMGR_HANDLE_T *handle, void *extra)
    IOFUNC_OCB_T    *ocb;
    int     sts;

    sts = iofunc_open (ctp, msg, &handle -> base, NULL, NULL);
    if (sts != EOK) {
        return (sts);

    ocb = calloc (1, sizeof (*ocb));
    if (ocb == NULL) {
        return (ENOMEM);

    // give them the unencoded size
    handle -> base.nbytes = optx * opty;

    sts = iofunc_ocb_attach (ctp, msg, &ocb -> base,
                             &handle -> base, NULL);
    return (sts);

The only thing that's unique in this io_open() handler is that we allocate the OCB ourselves (we do this because we need a non standard size), and then jam the nbytes member with the raw uncompressed size, as discussed above.

In an earlier version of the code, instead of using the raw uncompressed size, I decided to call the 7-segment render function and to GIF-encode the output. I thought this was a good idea, reasoning that every time the client calls open() on the resource, I should increment the number. This way, too, I could give a more “realistic” size for the file (turns out that the compressed file is on the order of 5% of the size of the raw image). Unfortunately, that didn't work out because a lot of things end up causing the io_open() handler to run—things like ls would stat() the file, resulting in an inaccurate count. Some utilities prefer to stat() the file first, and then open it and read the data, causing the numbers to jump unexpectedly. I removed the code that generates the compressed stream from io_open() and instead moved it down to the io_read().