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/fclose.c \
|
||||||
upstream-freebsd/lib/libc/stdio/flags.c \
|
upstream-freebsd/lib/libc/stdio/flags.c \
|
||||||
upstream-freebsd/lib/libc/stdio/fopen.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/makebuf.c \
|
||||||
upstream-freebsd/lib/libc/stdio/mktemp.c \
|
upstream-freebsd/lib/libc/stdio/mktemp.c \
|
||||||
upstream-freebsd/lib/libc/stdio/setvbuf.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/fwalk.c \
|
||||||
upstream-openbsd/lib/libc/stdio/fwide.c \
|
upstream-openbsd/lib/libc/stdio/fwide.c \
|
||||||
upstream-openbsd/lib/libc/stdio/fwprintf.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/fwscanf.c \
|
||||||
upstream-openbsd/lib/libc/stdio/getc.c \
|
upstream-openbsd/lib/libc/stdio/getc.c \
|
||||||
upstream-openbsd/lib/libc/stdio/getchar.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
|
* Copyright (c) 1990, 1993
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
* I/O descriptors for __sfvwrite().
|
* I/O descriptors for __sfvwrite().
|
||||||
*/
|
*/
|
||||||
struct __siov {
|
struct __siov {
|
||||||
const void *iov_base;
|
void *iov_base;
|
||||||
size_t iov_len;
|
size_t iov_len;
|
||||||
};
|
};
|
||||||
struct __suio {
|
struct __suio {
|
||||||
|
@ -46,3 +46,4 @@ struct __suio {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int __sfvwrite(FILE *, 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
|
* Copyright (c) 1990, 1993
|
||||||
* The Regents of the University of California. All rights reserved.
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
@ -30,67 +31,58 @@
|
||||||
* SUCH DAMAGE.
|
* 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 <stdio.h>
|
||||||
#include "un-namespace.h"
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "local.h"
|
#include "local.h"
|
||||||
#include "fvwrite.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.
|
* Write `count' objects (each size `size') from memory to the given file.
|
||||||
* Return the number of whole objects written.
|
* Return the number of whole objects written.
|
||||||
*/
|
*/
|
||||||
size_t
|
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;
|
size_t n;
|
||||||
struct __suio uio;
|
struct __suio uio;
|
||||||
struct __siov iov;
|
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))
|
if ((size >= MUL_NO_OVERFLOW || count >= MUL_NO_OVERFLOW) &&
|
||||||
return (0);
|
size > 0 && SIZE_MAX / size < count) {
|
||||||
|
errno = EOVERFLOW;
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
fp->_flags |= __SERR;
|
fp->_flags |= __SERR;
|
||||||
return (0);
|
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;
|
iov.iov_base = (void *)buf;
|
||||||
uio.uio_resid = iov.iov_len = n;
|
uio.uio_resid = iov.iov_len = n;
|
||||||
uio.uio_iov = &iov;
|
uio.uio_iov = &iov;
|
||||||
uio.uio_iovcnt = 1;
|
uio.uio_iovcnt = 1;
|
||||||
|
|
||||||
FLOCKFILE(fp);
|
|
||||||
ORIENT(fp, -1);
|
|
||||||
/*
|
/*
|
||||||
* The usual case is success (__sfvwrite returns 0);
|
* The usual case is success (__sfvwrite returns 0);
|
||||||
* skip the divide if this happens, since divides are
|
* skip the divide if this happens, since divides are
|
||||||
* generally slow and since this occurs whenever size==0.
|
* generally slow and since this occurs whenever size==0.
|
||||||
*/
|
*/
|
||||||
if (__sfvwrite(fp, &uio) != 0)
|
FLOCKFILE(fp);
|
||||||
count = (n - uio.uio_resid) / size;
|
_SET_ORIENTATION(fp, -1);
|
||||||
|
ret = __sfvwrite(fp, &uio);
|
||||||
FUNLOCKFILE(fp);
|
FUNLOCKFILE(fp);
|
||||||
return (count);
|
if (ret == 0)
|
||||||
|
return (count);
|
||||||
|
return ((n - uio.uio_resid) / size);
|
||||||
}
|
}
|
Loading…
Reference in a new issue