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;

Reply via email to