summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1999-08-07 17:35:59 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1999-08-07 17:35:59 +0000
commitd979bd14657315932ad5c6e70bcb81b039f10687 (patch)
tree60394dc8817ecf596754dc607826c70d3250ab66
parent25514829491ab4fdeb7a1818a8ce14e1f56e2b61 (diff)
If fread() returns EBADF, also set the error flag; tobez@plab.ku.dk
-rw-r--r--lib/libc/stdio/Makefile.inc4
-rw-r--r--lib/libc/stdio/asnprintf.c106
-rw-r--r--lib/libc/stdio/fputs.c3
-rw-r--r--lib/libc/stdio/fvwrite.c9
-rw-r--r--lib/libc/stdio/puts.c3
-rw-r--r--lib/libc/stdio/refill.c3
-rw-r--r--lib/libc/stdio/vasnprintf.c90
7 files changed, 211 insertions, 7 deletions
diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc
index 18eb2722926..8a2903a3e54 100644
--- a/lib/libc/stdio/Makefile.inc
+++ b/lib/libc/stdio/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.8 1998/11/20 11:18:48 d Exp $
+# $OpenBSD: Makefile.inc,v 1.9 1999/08/07 17:35:58 millert Exp $
# stdio sources
.PATH: ${LIBCSRCDIR}/stdio
@@ -14,7 +14,7 @@ SRCS+= asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c fflush.c fgetc.c \
scanf.c setbuf.c setbuffer.c setvbuf.c snprintf.c sprintf.c sscanf.c \
stdio.c tempnam.c tmpfile.c tmpnam.c ungetc.c vasprintf.c vfprintf.c \
vfscanf.c vprintf.c vscanf.c vsnprintf.c vsprintf.c vsscanf.c \
- wbuf.c wsetup.c flockfile.c
+ wbuf.c wsetup.c flockfile.c asnprintf.c vasnprintf.c
MAN+= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fopen.3 fputs.3 \
fread.3 fseek.3 funopen.3 getc.3 mktemp.3 perror.3 printf.3 putc.3 \
diff --git a/lib/libc/stdio/asnprintf.c b/lib/libc/stdio/asnprintf.c
new file mode 100644
index 00000000000..13db368376f
--- /dev/null
+++ b/lib/libc/stdio/asnprintf.c
@@ -0,0 +1,106 @@
+/* $OpenBSD: asnprintf.c,v 1.1 1999/08/07 17:35:58 millert Exp $ */
+
+/*
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: asnprintf.c,v 1.1 1999/08/07 17:35:58 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+int
+#if __STDC__
+asnprintf(char **str, size_t n, char const *fmt, ...)
+#else
+asnprintf(str, n, fmt, va_alist)
+ char **str;
+ size_t n;
+ const char *fmt;
+ va_dcl
+#endif
+{
+ int ret;
+ va_list ap;
+ FILE f;
+ unsigned char *_base;
+
+ /* While snprintf(3) specifies size_t stdio uses an int internally */
+ if (n > INT_MAX)
+ n = INT_MAX;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ f._file = -1;
+ f._flags = __SWR | __SSTR;
+ if (n > 0) {
+ f._flags |= __SALC | __SAMX;
+ f._bf._base = f._p = (unsigned char *)malloc(128);
+ if (f._bf._base == NULL)
+ goto err;
+ f._bf._size = f._w = 127; /* Leave room for the NUL */
+ f._blksize = n - 1;
+ } else {
+ f._bf._base = f._p = NULL;
+ f._bf._size = f._w = 0;
+ }
+ ret = vfprintf(&f, fmt, ap);
+ if (ret == -1)
+ goto err;
+ if (n > 0) {
+ *f._p = '\0';
+ va_end(ap);
+ if (ret + 1 < n) {
+ _base = realloc(f._bf._base, ret + 1);
+ if (_base == NULL)
+ goto err;
+ else
+ f._bf._base = _base;
+ }
+ }
+ *str = f._bf._base;
+ return (ret);
+
+err:
+ if (f._bf._base) {
+ free(f._bf._base);
+ f._bf._base = NULL;
+ }
+ *str = NULL;
+ errno = ENOMEM;
+ return (-1);
+}
diff --git a/lib/libc/stdio/fputs.c b/lib/libc/stdio/fputs.c
index b6d61573013..a7a1367ebc8 100644
--- a/lib/libc/stdio/fputs.c
+++ b/lib/libc/stdio/fputs.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: fputs.c,v 1.2 1996/08/19 08:32:43 tholo Exp $";
+static char rcsid[] = "$OpenBSD: fputs.c,v 1.3 1999/08/07 17:35:58 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
@@ -45,6 +45,7 @@ static char rcsid[] = "$OpenBSD: fputs.c,v 1.2 1996/08/19 08:32:43 tholo Exp $";
/*
* Write the given string to the given file.
*/
+int
fputs(s, fp)
const char *s;
FILE *fp;
diff --git a/lib/libc/stdio/fvwrite.c b/lib/libc/stdio/fvwrite.c
index ef854a3f9b0..444b33a6d59 100644
--- a/lib/libc/stdio/fvwrite.c
+++ b/lib/libc/stdio/fvwrite.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: fvwrite.c,v 1.8 1998/11/20 06:13:26 millert Exp $";
+static char rcsid[] = "$OpenBSD: fvwrite.c,v 1.9 1999/08/07 17:35:58 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
@@ -111,7 +111,9 @@ __sfvwrite(fp, uio)
do {
GETIOV(;);
if ((fp->_flags & (__SALC | __SSTR)) ==
- (__SALC | __SSTR) && fp->_w < len) {
+ (__SALC | __SSTR) && fp->_w < len &&
+ ((fp->_flags & __SAMX) == 0 || fp->_bf._size
+ <= fp->_blksize)) {
size_t blen = fp->_p - fp->_bf._base;
unsigned char *_base;
int _size;
@@ -121,6 +123,9 @@ __sfvwrite(fp, uio)
do {
_size = (_size << 1) + 1;
} while (_size < blen + len);
+ /* Apply maximum if v?asnprintf */
+ if ((fp->_flags & __SAMX))
+ _size = MIN(_size, fp->_blksize);
_base = realloc(fp->_bf._base, _size + 1);
if (_base == NULL)
goto err;
diff --git a/lib/libc/stdio/puts.c b/lib/libc/stdio/puts.c
index 67c90ee6ce8..bd40942b79d 100644
--- a/lib/libc/stdio/puts.c
+++ b/lib/libc/stdio/puts.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: puts.c,v 1.2 1996/08/19 08:32:59 tholo Exp $";
+static char rcsid[] = "$OpenBSD: puts.c,v 1.3 1999/08/07 17:35:58 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
@@ -45,6 +45,7 @@ static char rcsid[] = "$OpenBSD: puts.c,v 1.2 1996/08/19 08:32:59 tholo Exp $";
/*
* Write the given string to stdout, appending a newline.
*/
+int
puts(s)
char const *s;
{
diff --git a/lib/libc/stdio/refill.c b/lib/libc/stdio/refill.c
index 855e5311c39..865a503228b 100644
--- a/lib/libc/stdio/refill.c
+++ b/lib/libc/stdio/refill.c
@@ -35,7 +35,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: refill.c,v 1.3 1996/08/19 08:33:00 tholo Exp $";
+static char rcsid[] = "$OpenBSD: refill.c,v 1.4 1999/08/07 17:35:58 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <errno.h>
@@ -75,6 +75,7 @@ __srefill(fp)
if ((fp->_flags & __SRD) == 0) {
if ((fp->_flags & __SRW) == 0) {
errno = EBADF;
+ fp->_flags |= __SERR;
return (EOF);
}
/* switch to reading */
diff --git a/lib/libc/stdio/vasnprintf.c b/lib/libc/stdio/vasnprintf.c
new file mode 100644
index 00000000000..831eb5a5f04
--- /dev/null
+++ b/lib/libc/stdio/vasnprintf.c
@@ -0,0 +1,90 @@
+/* $OpenBSD: vasnprintf.c,v 1.1 1999/08/07 17:35:58 millert Exp $ */
+
+/*
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$OpenBSD: vasnprintf.c,v 1.1 1999/08/07 17:35:58 millert Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <limits.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+vasnprintf(str, n, fmt, ap)
+ char **str;
+ size_t n;
+ const char *fmt;
+ _BSD_VA_LIST_ ap;
+{
+ int ret;
+ FILE f;
+ unsigned char *_base;
+
+ /* While snprintf(3) specifies size_t stdio uses an int internally */
+ if (n > INT_MAX)
+ n = INT_MAX;
+ f._file = -1;
+ f._flags = __SWR | __SSTR;
+ if (n > 0) {
+ f._flags |= __SALC | __SAMX;
+ f._bf._base = f._p = (unsigned char *)malloc(128);
+ if (f._bf._base == NULL)
+ goto err;
+ f._bf._size = f._w = 127; /* Leave room for the NULL */
+ f._blksize = n - 1;
+ } else {
+ f._bf._base = f._p = NULL;
+ f._bf._size = f._w = 0;
+ }
+ ret = vfprintf(&f, fmt, ap);
+ if (ret == -1)
+ goto err;
+ if (n > 0) {
+ *f._p = '\0';
+ if (ret + 1 < n) {
+ _base = realloc(f._bf._base, f._bf._size + 1);
+ if (_base == NULL)
+ goto err;
+ else
+ f._bf._base = _base;
+ }
+ }
+ *str = f._bf._base;
+ return (ret);
+
+err:
+ if (f._bf._base) {
+ free(f._bf._base);
+ f._bf._base = NULL;
+ }
+ *str = NULL;
+ errno = ENOMEM;
+ return (-1);
+}