1 /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
3 * GNU Library General Public License (LGPL) version 2 or later.
5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
11 /* Given a writing stream with no buffered output, write the
12 * data in 'buf' (which may be the stream's bufstart) of size
13 * 'bufsize' to the stream. If a write error occurs, set the
14 * stream's error indicator and (if buffering) buffer as much
15 * data as possible (FBF) or only up to '\n' (LBF) to implement
16 * "as if fputc()" clause in the standard.
18 * Returns the number of bytes written and/or buffered.
21 * Calling with bufsize == 0 is permitted, and buf is ignored in
23 * We implement fflush() by setting bufpos to bufstart and passing
24 * bufstart as the buf arg. If there is a write error, the
25 * unwritten buffered data will simply be moved to the beginning
26 * of the buffer. Since the data obviously fits in the buffer
27 * and since there will be no '\n' chars in the buffer in the LBF
28 * case, no data will be lost.
29 * NOT THREADSAFE! Assumes stream already locked if necessary.
32 size_t attribute_hidden
__stdio_WRITE(register FILE *stream
,
33 register const unsigned char *buf
, size_t bufsize
)
38 __STDIO_STREAM_VALIDATE(stream
);
39 assert(stream
->__filedes
>= -2);
40 assert(__STDIO_STREAM_IS_WRITING(stream
));
41 assert(!__STDIO_STREAM_BUFFER_WUSED(stream
)); /* Buffer must be empty. */
46 stodo
= (todo
<= SSIZE_MAX
) ? todo
: SSIZE_MAX
;
47 rv
= __WRITE(stream
, (char *) buf
, stodo
);
49 #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
51 if (rv
> stodo
) { /* Wrote more than stodo! */
59 __STDIO_STREAM_SET_ERROR(stream
);
61 /* We buffer data on "transient" errors, but discard it
62 * on "hard" ones. Example of a hard error:
64 * close(fileno(stdout));
65 * printf("Hi there 1\n"); // EBADF
66 * dup2(good_fd, fileno(stdout));
67 * printf("Hi there 2\n"); // buffers new data
69 * This program should not print "Hi there 1" to good_fd.
70 * The rationale is that the caller of writing operation
71 * should check for error and act on it.
72 * If he didn't, then future users of the stream
73 * have no idea what to do.
74 * It's least confusing to at least not burden them with
75 * some hidden buffered crap in the buffer.
77 if (errno
!= EINTR
&& errno
!= EAGAIN
) {
78 /* do we have other "soft" errors? */
82 #ifdef __STDIO_BUFFERS
83 stodo
= __STDIO_STREAM_BUFFER_SIZE(stream
);
91 s
= stream
->__bufstart
;
96 && __STDIO_STREAM_IS_LBF(stream
)
104 stream
->__bufpos
= s
;
106 todo
-= (s
- stream
->__bufstart
);
108 #endif /* __STDIO_BUFFERS */
115 __STDIO_STREAM_VALIDATE(stream
);