2000-02-18 03:39:52 +08:00
|
|
|
/*
|
2007-07-14 04:37:53 +08:00
|
|
|
* Copyright (c) 1990 The Regents of the University of California.
|
2000-02-18 03:39:52 +08:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms are permitted
|
|
|
|
* provided that the above copyright notice and this paragraph are
|
|
|
|
* duplicated in all such forms and that any documentation,
|
2020-01-29 02:54:53 +08:00
|
|
|
* and/or other materials related to such
|
2000-02-18 03:39:52 +08:00
|
|
|
* distribution and use acknowledge that the software was developed
|
|
|
|
* by the University of California, Berkeley. The name of the
|
|
|
|
* University 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 WITHOUT ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
|
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
*/
|
2004-04-23 Artem B. Bityuckiy <abitytsky@softminecorp.com>
* libc/stdio/asprintf.c libc/stdio/clearerr.c,
libc/stdio/fclose.c libc/stdio/fcloseall.c libc/stdio/fdopen.c,
libc/stdio/feof.c libc/stdio/ferror.c libc/stdio/fflush.c,
libc/stdio/fgetc.c libc/stdio/fgetpos.c libc/stdio/fgets.c,
libc/stdio/fileno.c libc/stdio/findfp.c libc/stdio/fiprintf.c,
libc/stdio/flags.c libc/stdio/fopen.c libc/stdio/fprintf.c,
libc/stdio/fputc.c libc/stdio/fputs.c libc/stdio/fread.c,
libc/stdio/freopen.c libc/stdio/fscanf.c libc/stdio/fseek.c,
libc/stdio/fseeko.c libc/stdio/fsetpos.c libc/stdio/ftell.c,
libc/stdio/ftello.c libc/stdio/fvwrite.c libc/stdio/fwalk.c,
libc/stdio/fwrite.c libc/stdio/getc.c libc/stdio/getc_u.c,
libc/stdio/getchar.c libc/stdio/getchar_u.c,
libc/stdio/getdelim.c libc/stdio/getline.c libc/stdio/gets.c,
libc/stdio/getw.c libc/stdio/iprintf.c libc/stdio/local.h,
libc/stdio/makebuf.c libc/stdio/mktemp.c libc/stdio/perror.c,
libc/stdio/printf.c libc/stdio/putc.c libc/stdio/putc_u.c,
libc/stdio/putchar.c libc/stdio/putchar_u.c libc/stdio/puts.c,
libc/stdio/putw.c libc/stdio/refill.c libc/stdio/remove.c,
libc/stdio/rename.c libc/stdio/rewind.c libc/stdio/rget.c,
libc/stdio/scanf.c libc/stdio/setbuf.c libc/stdio/setbuffer.c,
libc/stdio/setlinebuf.c libc/stdio/setvbuf.c,
libc/stdio/siprintf.c libc/stdio/snprintf.c,
libc/stdio/sprintf.c libc/stdio/sscanf.c libc/stdio/stdio.c,
libc/stdio/tmpfile.c libc/stdio/tmpnam.c libc/stdio/ungetc.c,
libc/stdio/vasprintf.c libc/stdio/vfieeefp.h,
libc/stdio/vfprintf.c libc/stdio/vfscanf.c,
libc/stdio/vprintf.c libc/stdio/vscanf.c,
libc/stdio/vsnprintf.c libc/stdio/vsprintf.c,
libc/stdio/vsscanf.c libc/stdio/wbuf.c,
libc/stdio/wsetup.c: Perform minor formatting changes. Move
copyright notices to top of file, ensure that <_ansi.h> is
included, be consistent with open parentheses, use _DEFUN macro,
include "local.h" where needed, and remove various compiler
warnings.
2004-04-24 04:01:55 +08:00
|
|
|
/* No user fns here. Pesch 15apr92. */
|
2000-02-18 03:39:52 +08:00
|
|
|
|
2004-04-23 Artem B. Bityuckiy <abitytsky@softminecorp.com>
* libc/stdio/asprintf.c libc/stdio/clearerr.c,
libc/stdio/fclose.c libc/stdio/fcloseall.c libc/stdio/fdopen.c,
libc/stdio/feof.c libc/stdio/ferror.c libc/stdio/fflush.c,
libc/stdio/fgetc.c libc/stdio/fgetpos.c libc/stdio/fgets.c,
libc/stdio/fileno.c libc/stdio/findfp.c libc/stdio/fiprintf.c,
libc/stdio/flags.c libc/stdio/fopen.c libc/stdio/fprintf.c,
libc/stdio/fputc.c libc/stdio/fputs.c libc/stdio/fread.c,
libc/stdio/freopen.c libc/stdio/fscanf.c libc/stdio/fseek.c,
libc/stdio/fseeko.c libc/stdio/fsetpos.c libc/stdio/ftell.c,
libc/stdio/ftello.c libc/stdio/fvwrite.c libc/stdio/fwalk.c,
libc/stdio/fwrite.c libc/stdio/getc.c libc/stdio/getc_u.c,
libc/stdio/getchar.c libc/stdio/getchar_u.c,
libc/stdio/getdelim.c libc/stdio/getline.c libc/stdio/gets.c,
libc/stdio/getw.c libc/stdio/iprintf.c libc/stdio/local.h,
libc/stdio/makebuf.c libc/stdio/mktemp.c libc/stdio/perror.c,
libc/stdio/printf.c libc/stdio/putc.c libc/stdio/putc_u.c,
libc/stdio/putchar.c libc/stdio/putchar_u.c libc/stdio/puts.c,
libc/stdio/putw.c libc/stdio/refill.c libc/stdio/remove.c,
libc/stdio/rename.c libc/stdio/rewind.c libc/stdio/rget.c,
libc/stdio/scanf.c libc/stdio/setbuf.c libc/stdio/setbuffer.c,
libc/stdio/setlinebuf.c libc/stdio/setvbuf.c,
libc/stdio/siprintf.c libc/stdio/snprintf.c,
libc/stdio/sprintf.c libc/stdio/sscanf.c libc/stdio/stdio.c,
libc/stdio/tmpfile.c libc/stdio/tmpnam.c libc/stdio/ungetc.c,
libc/stdio/vasprintf.c libc/stdio/vfieeefp.h,
libc/stdio/vfprintf.c libc/stdio/vfscanf.c,
libc/stdio/vprintf.c libc/stdio/vscanf.c,
libc/stdio/vsnprintf.c libc/stdio/vsprintf.c,
libc/stdio/vsscanf.c libc/stdio/wbuf.c,
libc/stdio/wsetup.c: Perform minor formatting changes. Move
copyright notices to top of file, ensure that <_ansi.h> is
included, be consistent with open parentheses, use _DEFUN macro,
include "local.h" where needed, and remove various compiler
warnings.
2004-04-24 04:01:55 +08:00
|
|
|
#include <_ansi.h>
|
2000-02-18 03:39:52 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2002-07-05 02:56:17 +08:00
|
|
|
#include <stdlib.h>
|
2006-06-15 04:49:11 +08:00
|
|
|
#include <errno.h>
|
2013-11-04 22:18:44 +08:00
|
|
|
#include <limits.h>
|
2000-02-18 03:39:52 +08:00
|
|
|
#include "local.h"
|
|
|
|
#include "fvwrite.h"
|
|
|
|
|
|
|
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
2017-12-04 10:56:37 +08:00
|
|
|
#define COPY(n) (void) memmove ((void *) fp->_p, (void *) p, (size_t) (n))
|
2000-02-18 03:39:52 +08:00
|
|
|
|
|
|
|
#define GETIOV(extra_work) \
|
|
|
|
while (len == 0) \
|
|
|
|
{ \
|
|
|
|
extra_work; \
|
|
|
|
p = iov->iov_base; \
|
|
|
|
len = iov->iov_len; \
|
|
|
|
iov++; \
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write some memory regions. Return zero on success, EOF on error.
|
|
|
|
*
|
|
|
|
* This routine is large and unsightly, but most of the ugliness due
|
|
|
|
* to the three different kinds of output buffering is handled here.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int
|
2017-12-04 11:43:30 +08:00
|
|
|
__sfvwrite_r (struct _reent *ptr,
|
2017-12-04 09:31:41 +08:00
|
|
|
register FILE *fp,
|
2004-04-23 Artem B. Bityuckiy <abitytsky@softminecorp.com>
* libc/stdio/asprintf.c libc/stdio/clearerr.c,
libc/stdio/fclose.c libc/stdio/fcloseall.c libc/stdio/fdopen.c,
libc/stdio/feof.c libc/stdio/ferror.c libc/stdio/fflush.c,
libc/stdio/fgetc.c libc/stdio/fgetpos.c libc/stdio/fgets.c,
libc/stdio/fileno.c libc/stdio/findfp.c libc/stdio/fiprintf.c,
libc/stdio/flags.c libc/stdio/fopen.c libc/stdio/fprintf.c,
libc/stdio/fputc.c libc/stdio/fputs.c libc/stdio/fread.c,
libc/stdio/freopen.c libc/stdio/fscanf.c libc/stdio/fseek.c,
libc/stdio/fseeko.c libc/stdio/fsetpos.c libc/stdio/ftell.c,
libc/stdio/ftello.c libc/stdio/fvwrite.c libc/stdio/fwalk.c,
libc/stdio/fwrite.c libc/stdio/getc.c libc/stdio/getc_u.c,
libc/stdio/getchar.c libc/stdio/getchar_u.c,
libc/stdio/getdelim.c libc/stdio/getline.c libc/stdio/gets.c,
libc/stdio/getw.c libc/stdio/iprintf.c libc/stdio/local.h,
libc/stdio/makebuf.c libc/stdio/mktemp.c libc/stdio/perror.c,
libc/stdio/printf.c libc/stdio/putc.c libc/stdio/putc_u.c,
libc/stdio/putchar.c libc/stdio/putchar_u.c libc/stdio/puts.c,
libc/stdio/putw.c libc/stdio/refill.c libc/stdio/remove.c,
libc/stdio/rename.c libc/stdio/rewind.c libc/stdio/rget.c,
libc/stdio/scanf.c libc/stdio/setbuf.c libc/stdio/setbuffer.c,
libc/stdio/setlinebuf.c libc/stdio/setvbuf.c,
libc/stdio/siprintf.c libc/stdio/snprintf.c,
libc/stdio/sprintf.c libc/stdio/sscanf.c libc/stdio/stdio.c,
libc/stdio/tmpfile.c libc/stdio/tmpnam.c libc/stdio/ungetc.c,
libc/stdio/vasprintf.c libc/stdio/vfieeefp.h,
libc/stdio/vfprintf.c libc/stdio/vfscanf.c,
libc/stdio/vprintf.c libc/stdio/vscanf.c,
libc/stdio/vsnprintf.c libc/stdio/vsprintf.c,
libc/stdio/vsscanf.c libc/stdio/wbuf.c,
libc/stdio/wsetup.c: Perform minor formatting changes. Move
copyright notices to top of file, ensure that <_ansi.h> is
included, be consistent with open parentheses, use _DEFUN macro,
include "local.h" where needed, and remove various compiler
warnings.
2004-04-24 04:01:55 +08:00
|
|
|
register struct __suio *uio)
|
2000-02-18 03:39:52 +08:00
|
|
|
{
|
|
|
|
register size_t len;
|
2017-12-04 10:25:16 +08:00
|
|
|
register const char *p = NULL;
|
2000-02-18 03:39:52 +08:00
|
|
|
register struct __siov *iov;
|
2013-10-23 18:04:43 +08:00
|
|
|
register _READ_WRITE_RETURN_TYPE w, s;
|
2000-02-18 03:39:52 +08:00
|
|
|
char *nl;
|
|
|
|
int nlknown, nldist;
|
|
|
|
|
|
|
|
if ((len = uio->uio_resid) == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* make sure we can write */
|
2007-03-15 Eric Blake <ebb9@byu.net>
* libc/stdio/local.h (cantwrite, FREEUB, FREELB): Make reentrant.
(__smakebuf): Rename...
(__smakebuf_r): to this.
* libc/stdio/fvwrite.h (__swsetup_r): Rename, from __swsetup.
* libc/stdio/makebuf.c (__smakebuf): Detect failed asprint
allocation, then rename...
(__smakebuf_r): ...to this and fix reentrancy.
* libc/stdio/wsetup.c (__swsetup): Detect failed asprintf
allocation, then rename...
(__swsetup_r): ...to this and fix reentrancy.
* libc/stdio/fseek.c (_fseek_r): Fix reentrancy.
* libc/stdio/refill.c (__srefill_r): Likewise.
* libc/stdio/fclose.c (_fclose_r): Likewise.
* libc/stdio/fread.c (_fread_r): Likewise.
* libc/stdio/freopen.c (_freopen_r): Likewise.
* libc/stdio/wbuf.c (__swbuf_r): Likewise.
* libc/stdio64/fseeko64.c (_fseeko64_r): Likewise.
* libc/stdio/fvwrite.c (__sfvwrite_r): Set errno properly on
failed asprintf allocation, and fix reentrancy.
* libc/stdio/snprintf.c (snprintf, _snprintf_r): Report overflow,
as required by POSIX.
* libc/stdio/sniprintf.c (sniprintf, _sniprintf_r): Likewise.
* libc/stdio/vsnprintf.c (vsnprintf, _vsnprintf_r): Likewise.
* libc/stdio/vsniprintf.c (vsniprintf, _vsniprintf_r): Likewise.
2007-03-16 02:40:48 +08:00
|
|
|
if (cantwrite (ptr, fp))
|
2011-06-14 11:56:05 +08:00
|
|
|
return EOF;
|
2000-02-18 03:39:52 +08:00
|
|
|
|
|
|
|
iov = uio->uio_iov;
|
|
|
|
len = 0;
|
2000-05-03 11:57:19 +08:00
|
|
|
|
|
|
|
#ifdef __SCLE
|
|
|
|
if (fp->_flags & __SCLE) /* text mode */
|
|
|
|
{
|
|
|
|
do
|
2002-05-01 02:23:40 +08:00
|
|
|
{
|
|
|
|
GETIOV (;);
|
|
|
|
while (len > 0)
|
|
|
|
{
|
2004-04-23 Artem B. Bityuckiy <abitytsky@softminecorp.com>
* libc/stdio/asprintf.c libc/stdio/clearerr.c,
libc/stdio/fclose.c libc/stdio/fcloseall.c libc/stdio/fdopen.c,
libc/stdio/feof.c libc/stdio/ferror.c libc/stdio/fflush.c,
libc/stdio/fgetc.c libc/stdio/fgetpos.c libc/stdio/fgets.c,
libc/stdio/fileno.c libc/stdio/findfp.c libc/stdio/fiprintf.c,
libc/stdio/flags.c libc/stdio/fopen.c libc/stdio/fprintf.c,
libc/stdio/fputc.c libc/stdio/fputs.c libc/stdio/fread.c,
libc/stdio/freopen.c libc/stdio/fscanf.c libc/stdio/fseek.c,
libc/stdio/fseeko.c libc/stdio/fsetpos.c libc/stdio/ftell.c,
libc/stdio/ftello.c libc/stdio/fvwrite.c libc/stdio/fwalk.c,
libc/stdio/fwrite.c libc/stdio/getc.c libc/stdio/getc_u.c,
libc/stdio/getchar.c libc/stdio/getchar_u.c,
libc/stdio/getdelim.c libc/stdio/getline.c libc/stdio/gets.c,
libc/stdio/getw.c libc/stdio/iprintf.c libc/stdio/local.h,
libc/stdio/makebuf.c libc/stdio/mktemp.c libc/stdio/perror.c,
libc/stdio/printf.c libc/stdio/putc.c libc/stdio/putc_u.c,
libc/stdio/putchar.c libc/stdio/putchar_u.c libc/stdio/puts.c,
libc/stdio/putw.c libc/stdio/refill.c libc/stdio/remove.c,
libc/stdio/rename.c libc/stdio/rewind.c libc/stdio/rget.c,
libc/stdio/scanf.c libc/stdio/setbuf.c libc/stdio/setbuffer.c,
libc/stdio/setlinebuf.c libc/stdio/setvbuf.c,
libc/stdio/siprintf.c libc/stdio/snprintf.c,
libc/stdio/sprintf.c libc/stdio/sscanf.c libc/stdio/stdio.c,
libc/stdio/tmpfile.c libc/stdio/tmpnam.c libc/stdio/ungetc.c,
libc/stdio/vasprintf.c libc/stdio/vfieeefp.h,
libc/stdio/vfprintf.c libc/stdio/vfscanf.c,
libc/stdio/vprintf.c libc/stdio/vscanf.c,
libc/stdio/vsnprintf.c libc/stdio/vsprintf.c,
libc/stdio/vsscanf.c libc/stdio/wbuf.c,
libc/stdio/wsetup.c: Perform minor formatting changes. Move
copyright notices to top of file, ensure that <_ansi.h> is
included, be consistent with open parentheses, use _DEFUN macro,
include "local.h" where needed, and remove various compiler
warnings.
2004-04-24 04:01:55 +08:00
|
|
|
if (putc (*p, fp) == EOF)
|
2002-05-01 02:23:40 +08:00
|
|
|
return EOF;
|
|
|
|
p++;
|
|
|
|
len--;
|
|
|
|
uio->uio_resid--;
|
|
|
|
}
|
|
|
|
}
|
2000-05-03 11:57:19 +08:00
|
|
|
while (uio->uio_resid > 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2000-02-18 03:39:52 +08:00
|
|
|
if (fp->_flags & __SNBF)
|
|
|
|
{
|
|
|
|
/*
|
2013-11-04 22:18:44 +08:00
|
|
|
* Unbuffered: Split buffer in the largest multiple of BUFSIZ < INT_MAX
|
|
|
|
* as some legacy code may expect int instead of size_t.
|
2000-02-18 03:39:52 +08:00
|
|
|
*/
|
|
|
|
do
|
|
|
|
{
|
|
|
|
GETIOV (;);
|
2013-11-04 22:18:44 +08:00
|
|
|
w = fp->_write (ptr, fp->_cookie, p,
|
|
|
|
MIN (len, INT_MAX - INT_MAX % BUFSIZ));
|
2000-02-18 03:39:52 +08:00
|
|
|
if (w <= 0)
|
|
|
|
goto err;
|
|
|
|
p += w;
|
|
|
|
len -= w;
|
|
|
|
}
|
|
|
|
while ((uio->uio_resid -= w) != 0);
|
|
|
|
}
|
|
|
|
else if ((fp->_flags & __SLBF) == 0)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Fully buffered: fill partially full buffer, if any,
|
|
|
|
* and then flush. If there is no partial buffer, write
|
|
|
|
* one _bf._size byte chunk directly (without copying).
|
|
|
|
*
|
|
|
|
* String output is a special case: write as many bytes
|
|
|
|
* as fit, but pretend we wrote everything. This makes
|
|
|
|
* snprintf() return the number of bytes needed, rather
|
|
|
|
* than the number used, and avoids its write function
|
2002-07-05 02:56:17 +08:00
|
|
|
* (so that the write function can be invalid). If
|
|
|
|
* we are dealing with the asprintf routines, we will
|
|
|
|
* dynamically increase the buffer size as needed.
|
2000-02-18 03:39:52 +08:00
|
|
|
*/
|
|
|
|
do
|
|
|
|
{
|
|
|
|
GETIOV (;);
|
|
|
|
w = fp->_w;
|
|
|
|
if (fp->_flags & __SSTR)
|
|
|
|
{
|
2007-05-04 10:55:16 +08:00
|
|
|
if (len >= w && fp->_flags & (__SMBF | __SOPT))
|
2002-07-05 02:56:17 +08:00
|
|
|
{ /* must be asprintf family */
|
2007-03-13 04:30:08 +08:00
|
|
|
unsigned char *str;
|
2002-07-05 02:56:17 +08:00
|
|
|
int curpos = (fp->_p - fp->_bf._base);
|
2006-11-30 05:36:54 +08:00
|
|
|
/* Choose a geometric growth factor to avoid
|
|
|
|
quadratic realloc behavior, but use a rate less
|
|
|
|
than (1+sqrt(5))/2 to accomodate malloc
|
|
|
|
overhead. asprintf EXPECTS us to overallocate, so
|
|
|
|
that it can add a trailing \0 without
|
|
|
|
reallocating. The new allocation should thus be
|
|
|
|
max(prev_size*1.5, curpos+len+1). */
|
|
|
|
int newsize = fp->_bf._size * 3 / 2;
|
|
|
|
if (newsize < curpos + len + 1)
|
|
|
|
newsize = curpos + len + 1;
|
2007-05-04 10:55:16 +08:00
|
|
|
if (fp->_flags & __SOPT)
|
2004-07-16 23:47:15 +08:00
|
|
|
{
|
2007-05-04 10:55:16 +08:00
|
|
|
/* asnprintf leaves original buffer alone. */
|
|
|
|
str = (unsigned char *)_malloc_r (ptr, newsize);
|
|
|
|
if (!str)
|
|
|
|
{
|
2022-01-18 17:13:04 +08:00
|
|
|
_REENT_ERRNO(ptr) = ENOMEM;
|
2007-05-04 10:55:16 +08:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
memcpy (str, fp->_bf._base, curpos);
|
|
|
|
fp->_flags = (fp->_flags & ~__SOPT) | __SMBF;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
str = (unsigned char *)_realloc_r (ptr, fp->_bf._base,
|
|
|
|
newsize);
|
|
|
|
if (!str)
|
|
|
|
{
|
2011-12-20 17:06:58 +08:00
|
|
|
/* Free buffer which is no longer used and clear
|
|
|
|
__SMBF flag to avoid double free in fclose. */
|
2007-05-04 10:55:16 +08:00
|
|
|
_free_r (ptr, fp->_bf._base);
|
2011-12-20 17:06:58 +08:00
|
|
|
fp->_flags &= ~__SMBF;
|
2007-05-04 10:55:16 +08:00
|
|
|
/* Ensure correct errno, even if free changed it. */
|
2022-01-18 17:13:04 +08:00
|
|
|
_REENT_ERRNO(ptr) = ENOMEM;
|
2007-05-04 10:55:16 +08:00
|
|
|
goto err;
|
|
|
|
}
|
2004-07-16 23:47:15 +08:00
|
|
|
}
|
2007-03-13 04:30:08 +08:00
|
|
|
fp->_bf._base = str;
|
|
|
|
fp->_p = str + curpos;
|
2006-11-30 05:36:54 +08:00
|
|
|
fp->_bf._size = newsize;
|
|
|
|
w = len;
|
|
|
|
fp->_w = newsize - curpos;
|
2002-07-05 02:56:17 +08:00
|
|
|
}
|
2000-02-18 03:39:52 +08:00
|
|
|
if (len < w)
|
|
|
|
w = len;
|
|
|
|
COPY (w); /* copy MIN(fp->_w,len), */
|
|
|
|
fp->_w -= w;
|
|
|
|
fp->_p += w;
|
|
|
|
w = len; /* but pretend copied all */
|
|
|
|
}
|
2013-11-04 22:18:44 +08:00
|
|
|
else if (fp->_p > fp->_bf._base || len < fp->_bf._size)
|
2000-02-18 03:39:52 +08:00
|
|
|
{
|
2013-11-04 22:18:44 +08:00
|
|
|
/* pass through the buffer */
|
|
|
|
w = MIN (len, w);
|
2000-02-18 03:39:52 +08:00
|
|
|
COPY (w);
|
2013-11-04 22:18:44 +08:00
|
|
|
fp->_w -= w;
|
2000-02-18 03:39:52 +08:00
|
|
|
fp->_p += w;
|
2013-11-04 22:18:44 +08:00
|
|
|
if (fp->_w == 0 && _fflush_r (ptr, fp))
|
2000-02-18 03:39:52 +08:00
|
|
|
goto err;
|
|
|
|
}
|
2013-11-04 22:18:44 +08:00
|
|
|
else
|
2000-02-18 03:39:52 +08:00
|
|
|
{
|
|
|
|
/* write directly */
|
2013-11-04 22:18:44 +08:00
|
|
|
w = ((int)MIN (len, INT_MAX)) / fp->_bf._size * fp->_bf._size;
|
Implement funopen, fopencookie.
* libc/include/sys/reent.h (struct __sFILE, struct __sFILE64):
Switch to reentrant callbacks.
* libc/include/stdio.h (funopen): Fix declaration.
(fopencookie): Declare.
* libc/stdio/local.h (__sread, __swrite, __sseek, __sclose)
(__sseek64, __swrite64): Fix prototypes.
[__SCLE]: Pull in setmode declaration.
* libc/stdio/stdio.c (__sread, __swrite, __sseek, __sclose): Fix
reentrancy.
* libc/stdio64/stdio64.c (__sseek64_r, __swrite64_r): Delete.
(__sseek64, __swrite64): Fix reentrancy.
* libc/stdio/fseek.c (_fseek_r): Account for overflow, and fix
reentrancy.
* libc/stdio/ftell.c (_ftell_r): Likewise.
* libc/stdio/flags.c (__sflags): Don't lose __SAPP on "a+".
* libc/stdio/fclose.c (_fclose_r): Fix reentrancy.
* libc/stdio/freopen.c (_freopen_r): Likewise.
* libc/stdio/fvwrite.c (__sfvwrite_r): Likewise.
* libc/stdio/refill.c (__srefill_r): Likewise.
* libc/stdio/siscanf.c (eofread): Likewise.
* libc/stdio/sscanf.c (eofread): Likewise.
* libc/stdio/vsiscanf.c (eofread1): Likewise.
* libc/stdio/vsscanf.c (eofread1): Likewise.
* libc/stdio64/freopen64.c (_freopen64_r): Likewise.
* libc/stdio64/fseeko64.c (_fseeko64_r): Likewise.
* libc/stdio64/ftello64.c (_ftello64_r): Likewise.
* libc/stdio/fflush.c (fflush): Improve reentrancy, although more
could be fixed.
* libc/stdio/fopencookie.c (_fopencookie_r, fopencookie): New file.
* libc/stdio/funopen.c (_funopen_r, funopen): New file.
* libc/stdio/Makefile.am (ELIX_4_SOURCES, CHEWOUT_FILES): Build
new files.
* libc/stdio/Makefile.in: Regenerate.
2007-06-05 02:10:17 +08:00
|
|
|
w = fp->_write (ptr, fp->_cookie, p, w);
|
2000-02-18 03:39:52 +08:00
|
|
|
if (w <= 0)
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
p += w;
|
|
|
|
len -= w;
|
|
|
|
}
|
|
|
|
while ((uio->uio_resid -= w) != 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Line buffered: like fully buffered, but we
|
|
|
|
* must check for newlines. Compute the distance
|
|
|
|
* to the first newline (including the newline),
|
|
|
|
* or `infinity' if there is none, then pretend
|
|
|
|
* that the amount to write is MIN(len,nldist).
|
|
|
|
*/
|
|
|
|
nlknown = 0;
|
2004-04-23 Artem B. Bityuckiy <abitytsky@softminecorp.com>
* libc/stdio/asprintf.c libc/stdio/clearerr.c,
libc/stdio/fclose.c libc/stdio/fcloseall.c libc/stdio/fdopen.c,
libc/stdio/feof.c libc/stdio/ferror.c libc/stdio/fflush.c,
libc/stdio/fgetc.c libc/stdio/fgetpos.c libc/stdio/fgets.c,
libc/stdio/fileno.c libc/stdio/findfp.c libc/stdio/fiprintf.c,
libc/stdio/flags.c libc/stdio/fopen.c libc/stdio/fprintf.c,
libc/stdio/fputc.c libc/stdio/fputs.c libc/stdio/fread.c,
libc/stdio/freopen.c libc/stdio/fscanf.c libc/stdio/fseek.c,
libc/stdio/fseeko.c libc/stdio/fsetpos.c libc/stdio/ftell.c,
libc/stdio/ftello.c libc/stdio/fvwrite.c libc/stdio/fwalk.c,
libc/stdio/fwrite.c libc/stdio/getc.c libc/stdio/getc_u.c,
libc/stdio/getchar.c libc/stdio/getchar_u.c,
libc/stdio/getdelim.c libc/stdio/getline.c libc/stdio/gets.c,
libc/stdio/getw.c libc/stdio/iprintf.c libc/stdio/local.h,
libc/stdio/makebuf.c libc/stdio/mktemp.c libc/stdio/perror.c,
libc/stdio/printf.c libc/stdio/putc.c libc/stdio/putc_u.c,
libc/stdio/putchar.c libc/stdio/putchar_u.c libc/stdio/puts.c,
libc/stdio/putw.c libc/stdio/refill.c libc/stdio/remove.c,
libc/stdio/rename.c libc/stdio/rewind.c libc/stdio/rget.c,
libc/stdio/scanf.c libc/stdio/setbuf.c libc/stdio/setbuffer.c,
libc/stdio/setlinebuf.c libc/stdio/setvbuf.c,
libc/stdio/siprintf.c libc/stdio/snprintf.c,
libc/stdio/sprintf.c libc/stdio/sscanf.c libc/stdio/stdio.c,
libc/stdio/tmpfile.c libc/stdio/tmpnam.c libc/stdio/ungetc.c,
libc/stdio/vasprintf.c libc/stdio/vfieeefp.h,
libc/stdio/vfprintf.c libc/stdio/vfscanf.c,
libc/stdio/vprintf.c libc/stdio/vscanf.c,
libc/stdio/vsnprintf.c libc/stdio/vsprintf.c,
libc/stdio/vsscanf.c libc/stdio/wbuf.c,
libc/stdio/wsetup.c: Perform minor formatting changes. Move
copyright notices to top of file, ensure that <_ansi.h> is
included, be consistent with open parentheses, use _DEFUN macro,
include "local.h" where needed, and remove various compiler
warnings.
2004-04-24 04:01:55 +08:00
|
|
|
nldist = 0;
|
2000-02-18 03:39:52 +08:00
|
|
|
do
|
|
|
|
{
|
|
|
|
GETIOV (nlknown = 0);
|
|
|
|
if (!nlknown)
|
|
|
|
{
|
2017-12-04 10:53:22 +08:00
|
|
|
nl = memchr ((void *) p, '\n', len);
|
2000-02-18 03:39:52 +08:00
|
|
|
nldist = nl ? nl + 1 - p : len + 1;
|
|
|
|
nlknown = 1;
|
|
|
|
}
|
|
|
|
s = MIN (len, nldist);
|
|
|
|
w = fp->_w + fp->_bf._size;
|
|
|
|
if (fp->_p > fp->_bf._base && s > w)
|
|
|
|
{
|
|
|
|
COPY (w);
|
|
|
|
/* fp->_w -= w; */
|
|
|
|
fp->_p += w;
|
2007-07-14 04:37:53 +08:00
|
|
|
if (_fflush_r (ptr, fp))
|
2000-02-18 03:39:52 +08:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
else if (s >= (w = fp->_bf._size))
|
|
|
|
{
|
Implement funopen, fopencookie.
* libc/include/sys/reent.h (struct __sFILE, struct __sFILE64):
Switch to reentrant callbacks.
* libc/include/stdio.h (funopen): Fix declaration.
(fopencookie): Declare.
* libc/stdio/local.h (__sread, __swrite, __sseek, __sclose)
(__sseek64, __swrite64): Fix prototypes.
[__SCLE]: Pull in setmode declaration.
* libc/stdio/stdio.c (__sread, __swrite, __sseek, __sclose): Fix
reentrancy.
* libc/stdio64/stdio64.c (__sseek64_r, __swrite64_r): Delete.
(__sseek64, __swrite64): Fix reentrancy.
* libc/stdio/fseek.c (_fseek_r): Account for overflow, and fix
reentrancy.
* libc/stdio/ftell.c (_ftell_r): Likewise.
* libc/stdio/flags.c (__sflags): Don't lose __SAPP on "a+".
* libc/stdio/fclose.c (_fclose_r): Fix reentrancy.
* libc/stdio/freopen.c (_freopen_r): Likewise.
* libc/stdio/fvwrite.c (__sfvwrite_r): Likewise.
* libc/stdio/refill.c (__srefill_r): Likewise.
* libc/stdio/siscanf.c (eofread): Likewise.
* libc/stdio/sscanf.c (eofread): Likewise.
* libc/stdio/vsiscanf.c (eofread1): Likewise.
* libc/stdio/vsscanf.c (eofread1): Likewise.
* libc/stdio64/freopen64.c (_freopen64_r): Likewise.
* libc/stdio64/fseeko64.c (_fseeko64_r): Likewise.
* libc/stdio64/ftello64.c (_ftello64_r): Likewise.
* libc/stdio/fflush.c (fflush): Improve reentrancy, although more
could be fixed.
* libc/stdio/fopencookie.c (_fopencookie_r, fopencookie): New file.
* libc/stdio/funopen.c (_funopen_r, funopen): New file.
* libc/stdio/Makefile.am (ELIX_4_SOURCES, CHEWOUT_FILES): Build
new files.
* libc/stdio/Makefile.in: Regenerate.
2007-06-05 02:10:17 +08:00
|
|
|
w = fp->_write (ptr, fp->_cookie, p, w);
|
2000-02-18 03:39:52 +08:00
|
|
|
if (w <= 0)
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
w = s;
|
|
|
|
COPY (w);
|
|
|
|
fp->_w -= w;
|
|
|
|
fp->_p += w;
|
|
|
|
}
|
|
|
|
if ((nldist -= w) == 0)
|
|
|
|
{
|
|
|
|
/* copied the newline: flush and forget */
|
2007-07-14 04:37:53 +08:00
|
|
|
if (_fflush_r (ptr, fp))
|
2000-02-18 03:39:52 +08:00
|
|
|
goto err;
|
|
|
|
nlknown = 0;
|
|
|
|
}
|
|
|
|
p += w;
|
|
|
|
len -= w;
|
|
|
|
}
|
|
|
|
while ((uio->uio_resid -= w) != 0);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err:
|
|
|
|
fp->_flags |= __SERR;
|
|
|
|
return EOF;
|
|
|
|
}
|