1 /* Copyright (C) 1991 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA. */
25 /* Write NMEMB chunks of SIZE bytes each from PTR onto STREAM. */
27 DEFUN(fwrite, (ptr, size, nmemb, stream),
28 CONST PTR ptr AND size_t size AND
29 size_t nmemb AND register FILE *stream)
31 register CONST char *p = (CONST char *) ptr;
32 register size_t to_write = size * nmemb;
33 register size_t written = 0;
38 if (!__validfp(stream) || !stream->__mode.__write)
46 if (p == NULL || to_write == 0)
49 if (!stream->__seen || stream->__put_limit == stream->__buffer)
51 /* This stream has never been seen before.
52 Calling __flshfp will give it a buffer
53 and I/O functions if it needs them. */
54 if (__flshfp(stream, *p++) == EOF)
63 = stream->__room_funcs.__output == __default_room_functions.__output;
65 if (stream->__buffer == NULL && default_func &&
66 stream->__offset == stream->__target)
68 /* This is an unbuffered stream using the standard output
69 buffer-flushing function, so we just do a straight write. */
71 int count = (stream->__io_funcs.__write == NULL ? to_write :
72 (*stream->__io_funcs.__write)(stream->__cookie, p,
77 stream->__offset += count;
78 stream->__target = stream->__offset;
87 /* We ignore the end pointer here since we want to find out how much space
88 is really in the buffer, even for a line-buffered stream. */
89 buffer_space = stream->__bufsize - (stream->__bufp - stream->__buffer);
91 newlinep = (stream->__linebuf &&
92 memchr((CONST PTR) p, '\n', to_write) != NULL);
94 if (newlinep && stream->__bufp == stream->__buffer &&
95 stream->__offset == stream->__target)
96 /* The buffer's empty, and we want to write our data
97 out soon anyway, so just write it straight out. */
100 if (stream->__bufsize == 0 && !default_func)
102 /* No buffer, and a special function.
103 We can't do much better than putc. */
104 while (to_write-- > 0)
106 if (__flshfp(stream, *p++) == EOF)
112 else if (!default_func || buffer_space >= to_write)
114 /* There is enough room in the buffer for everything we
115 want to write or the user has specified his own output
116 buffer-flushing/expanding function. */
119 register size_t n = to_write;
121 if (n > buffer_space)
131 *stream->__bufp++ = *p++;
134 memcpy((PTR) stream->__bufp, (PTR) p, n);
139 if (buffer_space == 0 || (to_write == 0 && newlinep))
141 /* We've filled the buffer, so flush it. */
142 if (fflush(stream) == EOF)
148 /* It won't all fit in the buffer. */
150 if (stream->__bufp != stream->__buffer)
152 /* There are characters in the buffer. Flush them. */
153 if (__flshfp(stream, EOF) == EOF)
157 /* The buffer has been flushed.
158 Now either fill it or write directly. */
160 buffer_space = stream->__put_limit - stream->__bufp;
162 if (stream->__offset == stream->__target &&
163 (buffer_space < to_write || newlinep))
164 /* What we have to write is bigger than the buffer,
165 or it contains a newline and we're line-buffered,
169 /* It will fit in the buffer. */
174 return (size_t) written / size;