The io_close_ocb() function

Finally, here are the modifications required for the io_close_ocb() function:

static int
io_close_ocb (resmgr_context_t *ctp, void *reserved, RESMGR_OCB_T *ocb)
    int     tmp;

    if (ocb -> output) {
        free (ocb -> output);
        ocb -> output = NULL;

    // if we were writing, parse the input
    // buffer and possibly adjust the count
    if (ocb -> base.ioflag & _IO_FLAG_WR) {
        // ensure NUL terminated and correct size
        ocb -> wbuf [optd + 1] = 0;
        if (isdigit (*ocb -> wbuf)) {
            attr_gif.count = attr_txt.count = tmp = atoi (ocb -> wbuf);
            if (optS) {
                write_file (optS, tmp);

    return (iofunc_close_ocb_default (ctp, reserved, &ocb -> base));

All that's different in the io_close_ocb() function is that we look at the OCB's ioflag to determine if we were writing or not. Recall that the ioflag is the “open mode” plus one—by comparing against the constant _IO_FLAG_WR we can tell if the “write” bit is set. If the write bit is set, we were writing, therefore we process the buffer that we had been accumulating in the io_write(). First of all, we NULL-terminate the buffer at the position corresponding to the number of digits specified on the command line (the -d option, which sets optd). This ensures that the atoi() call doesn't run off the end of the string and into Deep Outer Space (DOS)—this is redundant because we calloc() the entire OCB, so there is a NULL there anyway. Finally, we write the persistent counter file if optS is non-NULL.

We check to see if the first character is indeed a digit, and jam the converted value into both attribute structures' count members. (The atoi() function stops at the first non digit.)

This is where you could add additional command parsing if you wanted to. For example, you might allow hexadecimal digits, or you might wish to change the background/foreground colors, etc., via simple strings that you could echo from the command line:

echo "bgcolor=#FFFF00" >/dev/webcounter.gif

This is left as an exercise for the reader.