static ssize_t wrapwrite(void *pdata, const char *buf, size_t len)
{
struct stdif *nf = pdata;
+ size_t off;
+ ssize_t ret;
- return(nf->write(nf->pdata, buf, len));
+ /*
+ * XXX? In seeming violation of its own manual, glibc requires the
+ * cookie-write function to complete writing the entire buffer,
+ * rather than working like write(2).
+ */
+ off = 0;
+ while(off < len) {
+ ret = nf->write(nf->pdata, buf + off, len - off);
+ if(ret < 0)
+ return(off);
+ off += ret;
+ }
+ return(off);
}
-static int wrapseek(void *pdata, off_t *pos, int whence)
+static int wrapseek(void *pdata, off64_t *pos, int whence)
{
struct stdif *nf = pdata;
off_t ret;
if(nf->close != NULL)
ret = nf->close(nf->pdata);
+ else
+ ret = 0;
free(nf);
return(ret);
}
if(nf->close != NULL)
ret = nf->close(nf->pdata);
+ else
+ ret = 0;
free(nf);
return(ret);
}
struct stdif *nf;
omalloc(nf);
- return(funopen(pdata, read?wrapread:NULL, write:wrapwrite:NULL, seek:wrapseek:NULL, wrapclose));
+ *nf = (struct stdif){.read = read, .write = write, .seek = seek, .close = close, .pdata = pdata};
+ return(funopen(nf, read?wrapread:NULL, write?wrapwrite:NULL, seek?wrapseek:NULL, wrapclose));
}
#else
#error "No stdio implementation for this system"