diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1999-08-07 17:35:59 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1999-08-07 17:35:59 +0000 |
commit | d979bd14657315932ad5c6e70bcb81b039f10687 (patch) | |
tree | 60394dc8817ecf596754dc607826c70d3250ab66 | |
parent | 25514829491ab4fdeb7a1818a8ce14e1f56e2b61 (diff) |
If fread() returns EBADF, also set the error flag; tobez@plab.ku.dk
-rw-r--r-- | lib/libc/stdio/Makefile.inc | 4 | ||||
-rw-r--r-- | lib/libc/stdio/asnprintf.c | 106 | ||||
-rw-r--r-- | lib/libc/stdio/fputs.c | 3 | ||||
-rw-r--r-- | lib/libc/stdio/fvwrite.c | 9 | ||||
-rw-r--r-- | lib/libc/stdio/puts.c | 3 | ||||
-rw-r--r-- | lib/libc/stdio/refill.c | 3 | ||||
-rw-r--r-- | lib/libc/stdio/vasnprintf.c | 90 |
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); +} |