X-Git-Url: http://git.csclub.uwaterloo.ca/?p=kopensolaris-gnu%2Fglibc.git;a=blobdiff_plain;f=stdio%2Ffwrite.c;h=236974388f89fc363e3edb5fb2c77fbe39575705;hp=9fa3f4adec861174e96b6a5eb9fb8e3a75d6af64;hb=1d42347e27bfa3b94529af46f3eb11f258faf01c;hpb=46b912c4154ce13faae4fc795a7ac6aba71e5a67 diff --git a/stdio/fwrite.c b/stdio/fwrite.c index 9fa3f4adec..236974388f 100644 --- a/stdio/fwrite.c +++ b/stdio/fwrite.c @@ -1,22 +1,21 @@ -/* Copyright (C) 1991 Free Software Foundation, Inc. -This file is part of the GNU C Library. +/* Copyright (C) 1991, 92, 93, 94, 96, 97, 98 Free Software Foundation, Inc. + This file is part of the GNU C Library. -The GNU C Library is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public License as -published by the Free Software Foundation; either version 2 of the -License, or (at your option) any later version. + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. -The GNU C Library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Library General Public License for more details. + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. -You should have received a copy of the GNU Library General Public -License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. */ + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ -#include #include #include #include @@ -24,24 +23,26 @@ Cambridge, MA 02139, USA. */ /* Write NMEMB chunks of SIZE bytes each from PTR onto STREAM. */ size_t -DEFUN(fwrite, (ptr, size, nmemb, stream), - CONST PTR ptr AND size_t size AND - size_t nmemb AND register FILE *stream) +fwrite (ptr, size, nmemb, stream) + const void *ptr; + size_t size; + size_t nmemb; + register FILE *stream; { - register CONST char *p = (CONST char *) ptr; + register const unsigned char *p = (const unsigned char *) ptr; register size_t to_write = size * nmemb; register size_t written = 0; int newlinep; size_t buffer_space; - char default_func; + int default_func; - if (!__validfp(stream) || !stream->__mode.__write) + if (!__validfp (stream) || !stream->__mode.__write) { - errno = EINVAL; + __set_errno (EINVAL); return 0; } - if (ferror(stream)) + if (ferror (stream)) return 0; if (p == NULL || to_write == 0) return 0; @@ -51,7 +52,7 @@ DEFUN(fwrite, (ptr, size, nmemb, stream), /* This stream has never been seen before. Calling __flshfp will give it a buffer and I/O functions if it needs them. */ - if (__flshfp(stream, *p++) == EOF) + if (__flshfp (stream, *p++) == EOF) return 0; if (--to_write == 0) return 1; @@ -62,11 +63,17 @@ DEFUN(fwrite, (ptr, size, nmemb, stream), default_func = stream->__room_funcs.__output == __default_room_functions.__output; - if (__stdio_check_offset (stream) == EOF) - { - stream->__error = 1; - goto done; - } + { + int save = errno; + + if (__stdio_check_offset (stream) == EOF && errno != ESPIPE) + { + stream->__error = 1; + goto done; + } + + __set_errno (save); + } if (stream->__buffer == NULL && default_func && stream->__offset == stream->__target) @@ -75,13 +82,17 @@ DEFUN(fwrite, (ptr, size, nmemb, stream), buffer-flushing function, so we just do a straight write. */ { int count = (stream->__io_funcs.__write == NULL ? to_write : - (*stream->__io_funcs.__write)(stream->__cookie, p, - to_write)); + (*stream->__io_funcs.__write) (stream->__cookie, + (const char *) p, + to_write)); if (count > 0) { written += count; - stream->__offset += count; - stream->__target = stream->__offset; + if (stream->__offset != -1) + { + stream->__offset += count; + stream->__target = stream->__offset; + } to_write -= count; p += count; } @@ -95,7 +106,7 @@ DEFUN(fwrite, (ptr, size, nmemb, stream), buffer_space = stream->__bufsize - (stream->__bufp - stream->__buffer); newlinep = (stream->__linebuf && - memchr((CONST PTR) p, '\n', to_write) != NULL); + memchr ((const void *) p, '\n', to_write) != NULL); if (newlinep && stream->__bufp == stream->__buffer && stream->__offset == stream->__target) @@ -109,46 +120,74 @@ DEFUN(fwrite, (ptr, size, nmemb, stream), We can't do much better than putc. */ while (to_write-- > 0) { - if (__flshfp(stream, *p++) == EOF) + if (__flshfp (stream, *p++) == EOF) break; else ++written; } } else if (!default_func || buffer_space >= to_write) - fill_buffer: - /* There is enough room in the buffer for everything we - want to write or the user has specified his own output - buffer-flushing/expanding function. */ - while (to_write > 0) - { - register size_t n = to_write; - - if (n > buffer_space) - n = buffer_space; - - buffer_space -= n; - - written += n; - to_write -= n; - - if (n < 20) - while (n-- > 0) - *stream->__bufp++ = *p++; - else - { - memcpy((PTR) stream->__bufp, (PTR) p, n); - stream->__bufp += n; - p += n; - } - - if (buffer_space == 0 || (to_write == 0 && newlinep)) - { - /* We've filled the buffer, so flush it. */ - if (fflush(stream) == EOF) - break; - } - } + { + /* There is enough room in the buffer for everything we want to write + or the user has specified his own output buffer-flushing/expanding + function. */ + fill_buffer: + while (to_write > 0) + { + register size_t n = to_write; + + if (n > buffer_space) + n = buffer_space; + + buffer_space -= n; + + written += n; + to_write -= n; + + if (n < 20) + while (n-- > 0) + *stream->__bufp++ = *p++; + else + { + memcpy ((void *) stream->__bufp, (void *) p, n); + stream->__bufp += n; + p += n; + } + + if (to_write == 0) + /* Done writing. */ + break; + else if (buffer_space == 0) + { + /* We have filled the buffer, so flush it. */ + if (fflush (stream) == EOF) + break; + + /* Reset our record of the space available in the buffer, + since we have just flushed it. */ + check_space: + buffer_space = (stream->__bufsize - + (stream->__bufp - stream->__buffer)); + if (buffer_space == 0) + { + /* With a custom output-room function, flushing might + not create any buffer space. Try writing a single + character to create the space. */ + if (__flshfp (stream, *p++) == EOF) + goto done; + ++written; + --to_write; + goto check_space; + } + } + } + + /* We have written all the data into the buffer. If we are + line-buffered and just put a newline in the buffer, flush now to + make sure it gets out. */ + if (newlinep) + fflush (stream); + } else { /* It won't all fit in the buffer. */ @@ -156,14 +195,14 @@ DEFUN(fwrite, (ptr, size, nmemb, stream), if (stream->__bufp != stream->__buffer) { /* There are characters in the buffer. Flush them. */ - if (__flshfp(stream, EOF) == EOF) + if (__flshfp (stream, EOF) == EOF) goto done; } /* The buffer has been flushed. Now either fill it or write directly. */ - buffer_space = stream->__put_limit - stream->__bufp; + buffer_space = stream->__bufsize - (stream->__bufp - stream->__buffer); if (stream->__offset == stream->__target && (buffer_space < to_write || newlinep)) @@ -179,3 +218,5 @@ DEFUN(fwrite, (ptr, size, nmemb, stream), done:; return (size_t) written / size; } + +weak_alias (fwrite, fwrite_unlocked)