Module Name: src Committed By: christos Date: Tue Mar 27 15:05:43 UTC 2012
Modified Files: src/lib/libc/stdio: Makefile.inc fflush.c findfp.c fmemopen.c freopen.c fseeko.c ftell.c ftello.c funopen.3 funopen.c fvwrite.c local.h refill.c sscanf.c stdio.c vfwprintf.c vsscanf.c vswscanf.c Log Message: - widen the internal read and write calls to match the syscalls - add funopen2() which provides access to flush() and the wider calls. - make use of the new flush call in fmemopen() To generate a diff of this commit: cvs rdiff -u -r1.40 -r1.41 src/lib/libc/stdio/Makefile.inc cvs rdiff -u -r1.17 -r1.18 src/lib/libc/stdio/fflush.c cvs rdiff -u -r1.27 -r1.28 src/lib/libc/stdio/findfp.c cvs rdiff -u -r1.6 -r1.7 src/lib/libc/stdio/fmemopen.c \ src/lib/libc/stdio/ftello.c cvs rdiff -u -r1.18 -r1.19 src/lib/libc/stdio/freopen.c \ src/lib/libc/stdio/funopen.3 src/lib/libc/stdio/vsscanf.c cvs rdiff -u -r1.11 -r1.12 src/lib/libc/stdio/fseeko.c cvs rdiff -u -r1.19 -r1.20 src/lib/libc/stdio/ftell.c \ src/lib/libc/stdio/sscanf.c cvs rdiff -u -r1.12 -r1.13 src/lib/libc/stdio/funopen.c cvs rdiff -u -r1.24 -r1.25 src/lib/libc/stdio/fvwrite.c cvs rdiff -u -r1.33 -r1.34 src/lib/libc/stdio/local.h cvs rdiff -u -r1.15 -r1.16 src/lib/libc/stdio/refill.c cvs rdiff -u -r1.20 -r1.21 src/lib/libc/stdio/stdio.c cvs rdiff -u -r1.29 -r1.30 src/lib/libc/stdio/vfwprintf.c cvs rdiff -u -r1.8 -r1.9 src/lib/libc/stdio/vswscanf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/stdio/Makefile.inc diff -u src/lib/libc/stdio/Makefile.inc:1.40 src/lib/libc/stdio/Makefile.inc:1.41 --- src/lib/libc/stdio/Makefile.inc:1.40 Wed Dec 22 11:59:10 2010 +++ src/lib/libc/stdio/Makefile.inc Tue Mar 27 11:05:42 2012 @@ -1,5 +1,5 @@ # from: @(#)Makefile.inc 5.7 (Berkeley) 6/27/91 -# $NetBSD: Makefile.inc,v 1.40 2010/12/22 16:59:10 christos Exp $ +# $NetBSD: Makefile.inc,v 1.41 2012/03/27 15:05:42 christos Exp $ # stdio sources .PATH: ${.CURDIR}/stdio @@ -45,6 +45,7 @@ MLINKS+=fread.3 fwrite.3 MLINKS+=fseek.3 fgetpos.3 fseek.3 fseeko.3 fseek.3 fsetpos.3 fseek.3 ftell.3 \ fseek.3 ftello.3 fseek.3 rewind.3 MLINKS+=funopen.3 fropen.3 funopen.3 fwopen.3 +MLINKS+=funopen.3 funopen2.3 funopen.3 fropen2.3 funopen.3 fwopen2.3 MLINKS+=getc.3 fgetc.3 getc.3 getc_unlocked.3 getc.3 getchar.3 \ getc.3 getchar_unlocked.3 getc.3 getw.3 MLINKS+=getdelim.3 getline.3 Index: src/lib/libc/stdio/fflush.c diff -u src/lib/libc/stdio/fflush.c:1.17 src/lib/libc/stdio/fflush.c:1.18 --- src/lib/libc/stdio/fflush.c:1.17 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/fflush.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: fflush.c,v 1.17 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: fflush.c,v 1.18 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)fflush.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: fflush.c,v 1.17 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: fflush.c,v 1.18 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -80,7 +80,8 @@ int __sflush(FILE *fp) { unsigned char *p; - int n, t; + size_t n; + ssize_t t; _DIAGASSERT(fp != NULL); @@ -92,8 +93,8 @@ __sflush(FILE *fp) return 0; ptrdiff_t tp = fp->_p - p; - _DIAGASSERT(__type_fit(int, tp)); - n = (int)tp; /* write this much */ + _DIAGASSERT(__type_fit(ssize_t, tp)); + n = (ssize_t)tp; /* write this much */ /* * Set these immediately to avoid problems with longjmp and to allow @@ -109,5 +110,7 @@ __sflush(FILE *fp) return EOF; } } + if (fp->_flush) + return (*fp->_flush)(fp->_cookie); return 0; } Index: src/lib/libc/stdio/findfp.c diff -u src/lib/libc/stdio/findfp.c:1.27 src/lib/libc/stdio/findfp.c:1.28 --- src/lib/libc/stdio/findfp.c:1.27 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/findfp.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: findfp.c,v 1.27 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: findfp.c,v 1.28 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)findfp.c 8.2 (Berkeley) 1/4/94"; #else -__RCSID("$NetBSD: findfp.c,v 1.27 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: findfp.c,v 1.28 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -56,13 +56,29 @@ int __sdidinit; #define NDYNAMIC 10 /* add ten more whenever necessary */ -#define std(flags, file) \ -/* p r w flags file bf lfbsize cookie close */ \ - { NULL, 0, 0, flags, file, { NULL, 0 }, 0, __sF + file, __sclose, \ -/* read seek write ext up */ \ - __sread, __sseek, __swrite, { (void *)(__sFext + file), 0 }, NULL, \ -/* ur ubuf, nbuf lb blksize offset */ \ - 0, { '\0', '\0', '\0' }, { '\0' }, { NULL, 0 }, 0, (off_t)0 } +#define std(flags, file) { \ + ._p = NULL, \ + ._r = 0, \ + ._w = 0, \ + ._flags = (flags), \ + ._file = (file), \ + ._bf = { ._base = NULL, ._size = 0 }, \ + ._lbfsize = 0, \ + ._cookie = __sF + (file), \ + ._close = __sclose, \ + ._read = __sread, \ + ._seek = __sseek, \ + ._write = __swrite, \ + ._ext = { ._base = (void *)(__sFext + (file)), ._size = 0 }, \ + ._up = NULL, \ + ._ur = 0, \ + ._ubuf = { [0] = '\0', [1] = '\0', [2] = '\0' }, \ + ._nbuf = { [0] = '\0' }, \ + ._flush = NULL, \ + ._lb_unused = { '\0' }, \ + ._blksize = 0, \ + ._offset = (off_t)0, \ +} /* the usual - (stdin + stdout + stderr) */ static FILE usual[FOPEN_MAX - 3]; @@ -99,8 +115,8 @@ moreglue(int n) struct __sfileext *pext; static FILE empty; - g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE) - + n * sizeof(struct __sfileext)); + g = malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE) + + n * sizeof(struct __sfileext)); if (g == NULL) return NULL; p = (FILE *)ALIGN((u_long)(g + 1)); @@ -129,6 +145,7 @@ __sfpinit(FILE *fp) fp->_lbfsize = 0; /* not line buffered */ fp->_file = -1; /* no file */ /* fp->_cookie = <any>; */ /* caller sets cookie, _read/_write etc */ + fp->_flush = NULL; /* default flush */ _UB(fp)._base = NULL; /* no ungetc buffer */ _UB(fp)._size = 0; memset(WCIO_GET(fp), 0, sizeof(struct wchar_io_data)); Index: src/lib/libc/stdio/fmemopen.c diff -u src/lib/libc/stdio/fmemopen.c:1.6 src/lib/libc/stdio/fmemopen.c:1.7 --- src/lib/libc/stdio/fmemopen.c:1.6 Sun Jan 22 13:36:17 2012 +++ src/lib/libc/stdio/fmemopen.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: fmemopen.c,v 1.6 2012/01/22 18:36:17 christos Exp $ */ +/* $NetBSD: fmemopen.c,v 1.7 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c)2007, 2010 Takehiko NOZAKI, @@ -29,7 +29,7 @@ #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: fmemopen.c,v 1.6 2012/01/22 18:36:17 christos Exp $"); +__RCSID("$NetBSD: fmemopen.c,v 1.7 2012/03/27 15:05:42 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #include <assert.h> @@ -46,11 +46,11 @@ struct fmemopen_cookie { char *head, *tail, *cur, *eob; }; -static int -fmemopen_read(void *cookie, char *buf, int nbytes) +static ssize_t +fmemopen_read(void *cookie, void *buf, size_t nbytes) { struct fmemopen_cookie *p; - char *s; + char *s, *b = buf; _DIAGASSERT(cookie != NULL); _DIAGASSERT(buf != NULL && nbytes > 0); @@ -60,17 +60,18 @@ fmemopen_read(void *cookie, char *buf, i do { if (p->cur == p->tail) break; - *buf++ = *p->cur++; + *b++ = *p->cur++; } while (--nbytes > 0); - return (int)(p->cur - s); + return (ssize_t)(p->cur - s); } -static int -fmemopen_write(void *cookie, const char *buf, int nbytes) +static ssize_t +fmemopen_write(void *cookie, const void *buf, size_t nbytes) { struct fmemopen_cookie *p; char *s; + const char *b = buf; _DIAGASSERT(cookie != NULL); _DIAGASSERT(buf != NULL && nbytes > 0); @@ -81,20 +82,34 @@ fmemopen_write(void *cookie, const char s = p->cur; do { if (p->cur == p->tail - 1) { - if (*buf == '\0') { + if (*b == '\0') { *p->cur++ = '\0'; goto ok; } break; } - *p->cur++ = *buf++; + *p->cur++ = *b++; } while (--nbytes > 0); *p->cur = '\0'; ok: if (p->cur > p->eob) p->eob = p->cur; - return (int)(p->cur - s); + return (ssize_t)(p->cur - s); +} + +static int +fmemopen_flush(void *cookie) +{ + struct fmemopen_cookie *p; + + _DIAGASSERT(cookie != NULL); + + p = (struct fmemopen_cookie *)cookie; + if (p->cur >= p->tail) + return -1; + *p->cur = '\0'; + return 0; } static off_t @@ -184,12 +199,12 @@ fmemopen(void * __restrict buf, size_t s goto release; } *cookie->head = '\0'; - fp->_close = &fmemopen_close1; + fp->_close = fmemopen_close1; } else { cookie->head = (char *)buf; if (oflags & O_TRUNC) *cookie->head = '\0'; - fp->_close = &fmemopen_close0; + fp->_close = fmemopen_close0; } cookie->tail = cookie->head + size; @@ -203,9 +218,10 @@ fmemopen(void * __restrict buf, size_t s cookie->cur = (oflags & O_APPEND) ? cookie->eob : cookie->head; fp->_flags = flags; - fp->_write = (flags & __SRD) ? NULL : &fmemopen_write; - fp->_read = (flags & __SWR) ? NULL : &fmemopen_read; - fp->_seek = &fmemopen_seek; + fp->_write = (flags & __SRD) ? NULL : fmemopen_write; + fp->_read = (flags & __SWR) ? NULL : fmemopen_read; + fp->_seek = fmemopen_seek; + fp->_flush = fmemopen_flush; fp->_cookie = (void *)cookie; return fp; Index: src/lib/libc/stdio/ftello.c diff -u src/lib/libc/stdio/ftello.c:1.6 src/lib/libc/stdio/ftello.c:1.7 --- src/lib/libc/stdio/ftello.c:1.6 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/ftello.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ftello.c,v 1.6 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: ftello.c,v 1.7 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -34,7 +34,7 @@ #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: ftello.c,v 1.6 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: ftello.c,v 1.7 2012/03/27 15:05:42 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #include "namespace.h" @@ -69,7 +69,7 @@ ftello(FILE *fp) * Find offset of underlying I/O object, then * adjust for buffered bytes. */ - __sflush(fp); /* may adjust seek offset on append stream */ + (void)__sflush(fp); /* may adjust seek offset on append stream */ if (fp->_flags & __SOFF) pos = fp->_offset; else { Index: src/lib/libc/stdio/freopen.c diff -u src/lib/libc/stdio/freopen.c:1.18 src/lib/libc/stdio/freopen.c:1.19 --- src/lib/libc/stdio/freopen.c:1.18 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/freopen.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: freopen.c,v 1.18 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: freopen.c,v 1.19 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)freopen.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: freopen.c,v 1.18 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: freopen.c,v 1.19 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -93,7 +93,7 @@ freopen(const char *file, const char *mo } else { /* flush the stream; ANSI doesn't require this. */ if (fp->_flags & __SWR) - (void) __sflush(fp); + (void)__sflush(fp); /* if close is NULL, closing is a no-op, hence pointless */ isopen = fp->_close != NULL; if ((wantfd = __sfileno(fp)) == -1 && isopen) { Index: src/lib/libc/stdio/funopen.3 diff -u src/lib/libc/stdio/funopen.3:1.18 src/lib/libc/stdio/funopen.3:1.19 --- src/lib/libc/stdio/funopen.3:1.18 Sun Jan 22 14:13:48 2012 +++ src/lib/libc/stdio/funopen.3 Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -.\" $NetBSD: funopen.3,v 1.18 2012/01/22 19:13:48 wiz Exp $ +.\" $NetBSD: funopen.3,v 1.19 2012/03/27 15:05:42 christos Exp $ .\" .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,13 +31,16 @@ .\" .\" @(#)funopen.3 8.1 (Berkeley) 6/9/93 .\" -.Dd January 22, 2012 +.Dd March 16, 2012 .Dt FUNOPEN 3 .Os .Sh NAME .Nm funopen , +.Nm funopen2 , .Nm fropen , -.Nm fwopen +.Nm fropen2 , +.Nm fwopen , +.Nm fwopen2 .Nd open a stream .Sh LIBRARY .Lb libc @@ -45,10 +48,15 @@ .In stdio.h .Ft FILE * .Fn funopen "void *cookie" "int (*readfn)(void *, char *, int)" "int (*writefn)(void *, const char *, int)" "off_t (*seekfn)(void *, off_t, int)" "int (*closefn)(void *)" +.Fn funopen2 "void *cookie" "ssize_t (*readfn)(void *, void *, size_t)" "ssize_t (*writefn)(void *, const void *, size_t)" "off_t (*seekfn)(void *, off_t, int)" "int (*flushfn)(void *)" "int (*closefn)(void *)" .Ft FILE * .Fn fropen "void *cookie" "int (*readfn)(void *, char *, int)" .Ft FILE * +.Fn fropen2 "void *cookie" "ssize_t (*readfn)(void *, void *, size_t)" +.Ft FILE * .Fn fwopen "void *cookie" "int (*writefn)(void *, const char *, int)" +.Ft FILE * +.Fn fwopen2 "void *cookie" "ssize_t (*writefn)(void *, const void *, size_t)" .Sh DESCRIPTION The .Fn funopen @@ -68,6 +76,14 @@ These functions will be used to read, write, seek and close the new stream. .Pp +The +.Fn funopen2 +function provides sightly different read and write signatures, which match +better the corresponding system calls, plus the ability to augment the +streams default flushing function. +If a flushing function is provided, then it is called after all data has +been written to the stream. +.Pp In general, omitting a function means that any attempt to perform the associated operation on the resulting stream will fail. If the close function is omitted, closing the stream will flush @@ -161,6 +177,10 @@ The .Fn funopen functions first appeared in .Bx 4.4 . +.The +.Fn funopen2 +functions first appeared in +.Nx 7 . .Sh CAVEATS All three functions are specific to .Nx Index: src/lib/libc/stdio/vsscanf.c diff -u src/lib/libc/stdio/vsscanf.c:1.18 src/lib/libc/stdio/vsscanf.c:1.19 --- src/lib/libc/stdio/vsscanf.c:1.18 Thu Mar 15 14:22:31 2012 +++ src/lib/libc/stdio/vsscanf.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vsscanf.c,v 1.18 2012/03/15 18:22:31 christos Exp $ */ +/* $NetBSD: vsscanf.c,v 1.19 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: vsscanf.c,v 1.18 2012/03/15 18:22:31 christos Exp $"); +__RCSID("$NetBSD: vsscanf.c,v 1.19 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -49,8 +49,8 @@ __RCSID("$NetBSD: vsscanf.c,v 1.18 2012/ #include "local.h" /* ARGSUSED */ -static int -eofread(void *cookie, char *buf, int len) +static ssize_t +eofread(void *cookie, void *buf, size_t len) { return 0; } Index: src/lib/libc/stdio/fseeko.c diff -u src/lib/libc/stdio/fseeko.c:1.11 src/lib/libc/stdio/fseeko.c:1.12 --- src/lib/libc/stdio/fseeko.c:1.11 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/fseeko.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: fseeko.c,v 1.11 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: fseeko.c,v 1.12 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -34,7 +34,7 @@ #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: fseeko.c,v 1.11 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: fseeko.c,v 1.12 2012/03/27 15:05:42 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #include "namespace.h" @@ -97,7 +97,7 @@ fseeko(FILE *fp, off_t offset, int whenc * we have to first find the current stream offset a la * ftell (see ftell for details). */ - __sflush(fp); /* may adjust seek offset on append stream */ + (void)__sflush(fp); /* may adjust seek offset on append stream */ if (fp->_flags & __SOFF) curoff = fp->_offset; else { Index: src/lib/libc/stdio/ftell.c diff -u src/lib/libc/stdio/ftell.c:1.19 src/lib/libc/stdio/ftell.c:1.20 --- src/lib/libc/stdio/ftell.c:1.19 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/ftell.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ftell.c,v 1.19 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: ftell.c,v 1.20 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)ftell.c 8.2 (Berkeley) 5/4/95"; #else -__RCSID("$NetBSD: ftell.c,v 1.19 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: ftell.c,v 1.20 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -68,7 +68,7 @@ ftell(FILE *fp) * Find offset of underlying I/O object, then * adjust for buffered bytes. */ - __sflush(fp); /* may adjust seek offset on append stream */ + (void)__sflush(fp); /* may adjust seek offset on append stream */ if (fp->_flags & __SOFF) pos = fp->_offset; else { Index: src/lib/libc/stdio/sscanf.c diff -u src/lib/libc/stdio/sscanf.c:1.19 src/lib/libc/stdio/sscanf.c:1.20 --- src/lib/libc/stdio/sscanf.c:1.19 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/sscanf.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: sscanf.c,v 1.19 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: sscanf.c,v 1.20 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)sscanf.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: sscanf.c,v 1.19 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: sscanf.c,v 1.20 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -51,8 +51,8 @@ __RCSID("$NetBSD: sscanf.c,v 1.19 2012/0 #include "local.h" /* ARGSUSED */ -static int -eofread(void *cookie, char *buf, int len) +static ssize_t +eofread(void *cookie, void *buf, size_t len) { return 0; Index: src/lib/libc/stdio/funopen.c diff -u src/lib/libc/stdio/funopen.c:1.12 src/lib/libc/stdio/funopen.c:1.13 --- src/lib/libc/stdio/funopen.c:1.12 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/funopen.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: funopen.c,v 1.12 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: funopen.c,v 1.13 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,20 +37,23 @@ #if 0 static char sccsid[] = "@(#)funopen.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: funopen.c,v 1.12 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: funopen.c,v 1.13 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ #include <stdio.h> #include <errno.h> +#include <stdlib.h> +#include <stddef.h> #include "reentrant.h" #include "local.h" FILE * -funopen(const void *cookie, - int (*readfn)(void *, char *, int), - int (*writefn)(void *, const char *, int), +funopen2(const void *cookie, + ssize_t (*readfn)(void *, void *, size_t), + ssize_t (*writefn)(void *, const void *, size_t), off_t (*seekfn)(void *, off_t, int), + int (*flushfn)(void *), int (*closefn)(void *)) { FILE *fp; @@ -76,6 +79,89 @@ funopen(const void *cookie, fp->_read = readfn; fp->_write = writefn; fp->_seek = seekfn; + fp->_flush = flushfn; fp->_close = closefn; return fp; } + +typedef struct { + void *cookie; + int (*readfn)(void *, char *, int); + int (*writefn)(void *, const char *, int); + off_t (*seekfn)(void *, off_t, int); + int (*closefn)(void *); +} dookie_t; + +static ssize_t +creadfn(void *dookie, void *buf, size_t len) +{ + dookie_t *d = dookie; + if (len > INT_MAX) + len = INT_MAX; + return (*d->readfn)(d->cookie, buf, (int)len); +} + +static ssize_t +cwritefn(void *dookie, const void *buf, size_t len) +{ + dookie_t *d = dookie; + ssize_t nr; + size_t l = len; + const char *b = buf; + + while (l) { + size_t nw = l > INT_MAX ? INT_MAX : l; + nr = (*d->writefn)(d->cookie, buf, (int)nw); + if (nr == -1) { + if (len == l) + return -1; + else + return len - l; + } + b += nr; + l -= nr; + } + return len; +} + +static off_t +cseekfn(void *dookie, off_t off, int whence) +{ + dookie_t *d = dookie; + return (*d->seekfn)(d->cookie, off, whence); +} + +static int +cclosefn(void *dookie) +{ + dookie_t *d = dookie; + void *c = d->cookie; + int (*cf)(void *) = d->closefn; + free(dookie); + return (*cf)(c); +} + +FILE * +funopen(const void *cookie, + int (*readfn)(void *, char *, int), + int (*writefn)(void *, const char *, int), + off_t (*seekfn)(void *, off_t, int), + int (*closefn)(void *)) +{ + dookie_t *d; + FILE *fp; + + if ((d = malloc(sizeof(*d))) == NULL) + return NULL; + + d->cookie = __UNCONST(cookie); + d->readfn = readfn; + d->writefn = writefn; + d->seekfn = seekfn; + d->closefn = closefn; + fp = funopen2(d, creadfn, cwritefn, cseekfn, NULL, cclosefn); + if (fp != NULL) + return fp; + free(d); + return NULL; + } Index: src/lib/libc/stdio/fvwrite.c diff -u src/lib/libc/stdio/fvwrite.c:1.24 src/lib/libc/stdio/fvwrite.c:1.25 --- src/lib/libc/stdio/fvwrite.c:1.24 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/fvwrite.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: fvwrite.c,v 1.24 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: fvwrite.c,v 1.25 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)fvwrite.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: fvwrite.c,v 1.24 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: fvwrite.c,v 1.25 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -63,14 +63,15 @@ __sfvwrite(FILE *fp, struct __suio *uio) size_t len; char *p; struct __siov *iov; - int w, s; + int s; + ssize_t w; char *nl; size_t nlknown, nldist; _DIAGASSERT(fp != NULL); _DIAGASSERT(uio != NULL); - if ((int)uio->uio_resid < 0) { + if ((ssize_t)uio->uio_resid < 0) { errno = EINVAL; return EOF; } @@ -102,8 +103,7 @@ __sfvwrite(FILE *fp, struct __suio *uio) */ do { GETIOV(;); - w = (*fp->_write)(fp->_cookie, p, - (int)MIN(len, BUFSIZ)); + w = (*fp->_write)(fp->_cookie, p, MIN(len, BUFSIZ)); if (w <= 0) goto err; p += w; @@ -146,11 +146,11 @@ __sfvwrite(FILE *fp, struct __suio *uio) w = fp->_w; if (fp->_flags & __SSTR) { if (len < (size_t)w) - w = (int)len; + w = len; COPY(w); /* copy MIN(fp->_w,len), */ - fp->_w -= w; + fp->_w -= (int)w; fp->_p += w; - w = (int)len; /* but pretend copied all */ + w = len; /* but pretend copied all */ } else if (fp->_p > fp->_bf._base && len > (size_t)w) { /* fill and flush */ COPY(w); @@ -160,14 +160,14 @@ __sfvwrite(FILE *fp, struct __suio *uio) goto err; } else if (len >= (size_t)(w = fp->_bf._size)) { /* write directly */ - w = (*fp->_write)(fp->_cookie, p, w); + w = (*fp->_write)(fp->_cookie, p, (size_t)w); if (w <= 0) goto err; } else { /* fill and done */ - w = (int)len; + w = len; COPY(w); - fp->_w -= w; + fp->_w -= (int)w; fp->_p += w; } p += w; @@ -199,13 +199,13 @@ __sfvwrite(FILE *fp, struct __suio *uio) if (fflush(fp)) goto err; } else if (s >= (w = fp->_bf._size)) { - w = (*fp->_write)(fp->_cookie, p, w); + w = (*fp->_write)(fp->_cookie, p, (size_t)w); if (w <= 0) goto err; } else { w = s; COPY(w); - fp->_w -= w; + fp->_w -= (int)w; fp->_p += w; } if ((nldist -= w) == 0) { Index: src/lib/libc/stdio/local.h diff -u src/lib/libc/stdio/local.h:1.33 src/lib/libc/stdio/local.h:1.34 --- src/lib/libc/stdio/local.h:1.33 Thu Mar 15 09:23:10 2012 +++ src/lib/libc/stdio/local.h Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: local.h,v 1.33 2012/03/15 13:23:10 christos Exp $ */ +/* $NetBSD: local.h,v 1.34 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -50,8 +50,8 @@ extern int __sflush(FILE *); extern FILE *__sfp(void); extern void __sfpinit(FILE *); extern int __srefill(FILE *); -extern int __sread(void *, char *, int); -extern int __swrite(void *, char const *, int); +extern ssize_t __sread(void *, void *, size_t); +extern ssize_t __swrite(void *, const void *, size_t); extern off_t __sseek(void *, off_t, int); extern int __sclose(void *); extern void __sinit(void); Index: src/lib/libc/stdio/refill.c diff -u src/lib/libc/stdio/refill.c:1.15 src/lib/libc/stdio/refill.c:1.16 --- src/lib/libc/stdio/refill.c:1.15 Thu Mar 15 14:22:30 2012 +++ src/lib/libc/stdio/refill.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: refill.c,v 1.15 2012/03/15 18:22:30 christos Exp $ */ +/* $NetBSD: refill.c,v 1.16 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)refill.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: refill.c,v 1.15 2012/03/15 18:22:30 christos Exp $"); +__RCSID("$NetBSD: refill.c,v 1.16 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -129,7 +129,8 @@ __srefill(FILE *fp) rwlock_unlock(&__sfp_lock); } fp->_p = fp->_bf._base; - fp->_r = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size); + fp->_r = (int)(*fp->_read)(fp->_cookie, (char *)fp->_p, + (size_t)fp->_bf._size); fp->_flags &= ~__SMOD; /* buffer contents are again pristine */ if (fp->_r <= 0) { if (fp->_r == 0) Index: src/lib/libc/stdio/stdio.c diff -u src/lib/libc/stdio/stdio.c:1.20 src/lib/libc/stdio/stdio.c:1.21 --- src/lib/libc/stdio/stdio.c:1.20 Mon Mar 19 21:42:59 2012 +++ src/lib/libc/stdio/stdio.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: stdio.c,v 1.20 2012/03/20 01:42:59 christos Exp $ */ +/* $NetBSD: stdio.c,v 1.21 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)stdio.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: stdio.c,v 1.20 2012/03/20 01:42:59 christos Exp $"); +__RCSID("$NetBSD: stdio.c,v 1.21 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -56,37 +56,40 @@ __RCSID("$NetBSD: stdio.c,v 1.20 2012/03 * Small standard I/O/seek/close functions. * These maintain the `known seek offset' for seek optimisation. */ -int -__sread(void *cookie, char *buf, int n) +ssize_t +__sread(void *cookie, void *buf, size_t n) { FILE *fp = cookie; ssize_t ret; - _DIAGASSERT(fp != NULL); + _DIAGASSERT(cookie != NULL); + _DIAGASSERT(cookie == fp->_cookie); _DIAGASSERT(buf != NULL); - ret = read(__sfileno(fp), buf, (size_t)n); + ret = read(__sfileno(fp), buf, n); /* if the read succeeded, update the current offset */ if (ret >= 0) fp->_offset += ret; else fp->_flags &= ~__SOFF; /* paranoia */ - return (int)ret; + return ret; } -int -__swrite(void *cookie, char const *buf, int n) +ssize_t +__swrite(void *cookie, const void *buf, size_t n) { FILE *fp = cookie; _DIAGASSERT(cookie != NULL); + _DIAGASSERT(cookie == fp->_cookie); _DIAGASSERT(buf != NULL); if (fp->_flags & __SAPP) - (void) lseek(__sfileno(fp), (off_t)0, SEEK_END); + if (lseek(__sfileno(fp), (off_t)0, SEEK_END) == (off_t)-1) + return -1; fp->_flags &= ~__SOFF; /* in case FAPPEND mode is set */ - return (int)write(__sfileno(fp), buf, (size_t)n); + return write(__sfileno(fp), buf, n); } off_t @@ -95,10 +98,11 @@ __sseek(void *cookie, off_t offset, int FILE *fp = cookie; off_t ret; - _DIAGASSERT(fp != NULL); + _DIAGASSERT(cookie != NULL); + _DIAGASSERT(cookie == fp->_cookie); ret = lseek(__sfileno(fp), offset, whence); - if (ret == -1L) + if (ret == (off_t)-1L) fp->_flags &= ~__SOFF; else { fp->_flags |= __SOFF; @@ -110,8 +114,10 @@ __sseek(void *cookie, off_t offset, int int __sclose(void *cookie) { + FILE *fp = cookie; _DIAGASSERT(cookie != NULL); + _DIAGASSERT(cookie == fp->_cookie); - return close(__sfileno((FILE *)cookie)); + return close(__sfileno(fp)); } Index: src/lib/libc/stdio/vfwprintf.c diff -u src/lib/libc/stdio/vfwprintf.c:1.29 src/lib/libc/stdio/vfwprintf.c:1.30 --- src/lib/libc/stdio/vfwprintf.c:1.29 Wed Mar 21 10:20:47 2012 +++ src/lib/libc/stdio/vfwprintf.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vfwprintf.c,v 1.29 2012/03/21 14:20:47 christos Exp $ */ +/* $NetBSD: vfwprintf.c,v 1.30 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -38,7 +38,7 @@ static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; __FBSDID("$FreeBSD: src/lib/libc/stdio/vfwprintf.c,v 1.27 2007/01/09 00:28:08 imp Exp $"); #else -__RCSID("$NetBSD: vfwprintf.c,v 1.29 2012/03/21 14:20:47 christos Exp $"); +__RCSID("$NetBSD: vfwprintf.c,v 1.30 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -170,6 +170,7 @@ __sbprintf(FILE *fp, const CHAR_T *fmt, fake._file = fp->_file; fake._cookie = fp->_cookie; fake._write = fp->_write; + fake._flush = fp->_flush; /* set up the buffer */ fake._bf._base = fake._p = buf; Index: src/lib/libc/stdio/vswscanf.c diff -u src/lib/libc/stdio/vswscanf.c:1.8 src/lib/libc/stdio/vswscanf.c:1.9 --- src/lib/libc/stdio/vswscanf.c:1.8 Thu Mar 15 14:22:31 2012 +++ src/lib/libc/stdio/vswscanf.c Tue Mar 27 11:05:42 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: vswscanf.c,v 1.8 2012/03/15 18:22:31 christos Exp $ */ +/* $NetBSD: vswscanf.c,v 1.9 2012/03/27 15:05:42 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -42,7 +42,7 @@ static char sccsid[] = "@(#)vsscanf.c 8.1 (Berkeley) 6/4/93"; __FBSDID("$FreeBSD: src/lib/libc/stdio/vswscanf.c,v 1.3 2004/04/07 09:55:05 tjr Exp $"); #else -__RCSID("$NetBSD: vswscanf.c,v 1.8 2012/03/15 18:22:31 christos Exp $"); +__RCSID("$NetBSD: vswscanf.c,v 1.9 2012/03/27 15:05:42 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -56,9 +56,9 @@ __RCSID("$NetBSD: vswscanf.c,v 1.8 2012/ #include "reentrant.h" #include "local.h" -static int +static ssize_t /*ARGSUSED*/ -eofread(void *cookie, char *buf, int len) +eofread(void *cookie, void *buf, size_t len) { return 0;