Merge "Switch to current upstream OpenBSD fwrite.c."
This commit is contained in:
commit
640b4a5a64
3 changed files with 27 additions and 34 deletions
|
@ -223,7 +223,6 @@ libc_upstream_freebsd_src_files := \
|
|||
upstream-freebsd/lib/libc/stdio/fclose.c \
|
||||
upstream-freebsd/lib/libc/stdio/flags.c \
|
||||
upstream-freebsd/lib/libc/stdio/fopen.c \
|
||||
upstream-freebsd/lib/libc/stdio/fwrite.c \
|
||||
upstream-freebsd/lib/libc/stdio/makebuf.c \
|
||||
upstream-freebsd/lib/libc/stdio/mktemp.c \
|
||||
upstream-freebsd/lib/libc/stdio/setvbuf.c \
|
||||
|
@ -388,6 +387,7 @@ libc_upstream_openbsd_src_files := \
|
|||
upstream-openbsd/lib/libc/stdio/fwalk.c \
|
||||
upstream-openbsd/lib/libc/stdio/fwide.c \
|
||||
upstream-openbsd/lib/libc/stdio/fwprintf.c \
|
||||
upstream-openbsd/lib/libc/stdio/fwrite.c \
|
||||
upstream-openbsd/lib/libc/stdio/fwscanf.c \
|
||||
upstream-openbsd/lib/libc/stdio/getc.c \
|
||||
upstream-openbsd/lib/libc/stdio/getchar.c \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: fvwrite.h,v 1.5 2003/06/02 20:18:37 millert Exp $ */
|
||||
/* $OpenBSD: fvwrite.h,v 1.6 2013/11/12 07:04:35 deraadt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
|
@ -36,7 +36,7 @@
|
|||
* I/O descriptors for __sfvwrite().
|
||||
*/
|
||||
struct __siov {
|
||||
const void *iov_base;
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
struct __suio {
|
||||
|
@ -46,3 +46,4 @@ struct __suio {
|
|||
};
|
||||
|
||||
extern int __sfvwrite(FILE *, struct __suio *);
|
||||
wint_t __fputwc_unlock(wchar_t wc, FILE *fp);
|
|
@ -1,3 +1,4 @@
|
|||
/* $OpenBSD: fwrite.c,v 1.11 2014/05/01 16:40:36 deraadt Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
|
@ -30,67 +31,58 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "un-namespace.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include "local.h"
|
||||
#include "fvwrite.h"
|
||||
#include "libc_private.h"
|
||||
|
||||
#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
|
||||
|
||||
/*
|
||||
* Write `count' objects (each size `size') from memory to the given file.
|
||||
* Return the number of whole objects written.
|
||||
*/
|
||||
size_t
|
||||
fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict fp)
|
||||
fwrite(const void *buf, size_t size, size_t count, FILE *fp)
|
||||
{
|
||||
size_t n;
|
||||
struct __suio uio;
|
||||
struct __siov iov;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* ANSI and SUSv2 require a return value of 0 if size or count are 0.
|
||||
* Extension: Catch integer overflow
|
||||
*/
|
||||
if ((count == 0) || (size == 0))
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Check for integer overflow. As an optimization, first check that
|
||||
* at least one of {count, size} is at least 2^16, since if both
|
||||
* values are less than that, their product can't possible overflow
|
||||
* (size_t is always at least 32 bits on FreeBSD).
|
||||
*/
|
||||
if (((count | size) > 0xFFFF) &&
|
||||
(count > SIZE_MAX / size)) {
|
||||
errno = EINVAL;
|
||||
if ((size >= MUL_NO_OVERFLOW || count >= MUL_NO_OVERFLOW) &&
|
||||
size > 0 && SIZE_MAX / size < count) {
|
||||
errno = EOVERFLOW;
|
||||
fp->_flags |= __SERR;
|
||||
return (0);
|
||||
}
|
||||
|
||||
n = count * size;
|
||||
/*
|
||||
* ANSI and SUSv2 require a return value of 0 if size or count are 0.
|
||||
*/
|
||||
if ((n = count * size) == 0)
|
||||
return (0);
|
||||
|
||||
iov.iov_base = (void *)buf;
|
||||
uio.uio_resid = iov.iov_len = n;
|
||||
uio.uio_iov = &iov;
|
||||
uio.uio_iovcnt = 1;
|
||||
|
||||
FLOCKFILE(fp);
|
||||
ORIENT(fp, -1);
|
||||
/*
|
||||
* The usual case is success (__sfvwrite returns 0);
|
||||
* skip the divide if this happens, since divides are
|
||||
* generally slow and since this occurs whenever size==0.
|
||||
*/
|
||||
if (__sfvwrite(fp, &uio) != 0)
|
||||
count = (n - uio.uio_resid) / size;
|
||||
FLOCKFILE(fp);
|
||||
_SET_ORIENTATION(fp, -1);
|
||||
ret = __sfvwrite(fp, &uio);
|
||||
FUNLOCKFILE(fp);
|
||||
return (count);
|
||||
if (ret == 0)
|
||||
return (count);
|
||||
return ((n - uio.uio_resid) / size);
|
||||
}
|
Loading…
Reference in a new issue