X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Futils.c;h=b37430d8ea32adf86438298e9e25e92d14d20fb3;hb=407963f25c664cd1450ec5f6eeb80c449ff57e74;hp=ed22b429910252a1cc893a2d1d2b8af4ebacf316;hpb=2b8eb6dfb02dc93372c5e0a4efa6dff73a8ba004;p=ashd.git diff --git a/lib/utils.c b/lib/utils.c index ed22b42..b37430d 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -495,11 +495,25 @@ static ssize_t wrapread(void *pdata, char *buf, size_t len) 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; @@ -518,6 +532,8 @@ static int wrapclose(void *pdata) if(nf->close != NULL) ret = nf->close(nf->pdata); + else + ret = 0; free(nf); return(ret); } @@ -581,6 +597,8 @@ static int wrapclose(void *pdata) if(nf->close != NULL) ret = nf->close(nf->pdata); + else + ret = 0; free(nf); return(ret); } @@ -594,7 +612,8 @@ FILE *funstdio(void *pdata, 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"