blob: bf527785259c7d096a89edc9b466f9af1a242d60 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
2 *
3 * GNU Library General Public License (LGPL) version 2 or later.
4 *
5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
6 */
7
8#include "_stdio.h"
9
10
11#ifdef __STDIO_BUFFERS
12
13/* Either buffer data or (commit buffer if necessary and) write. */
14
15size_t attribute_hidden __stdio_fwrite(const unsigned char * __restrict buffer,
16 size_t bytes,
17 register FILE * __restrict stream)
18{
19 size_t pending;
20 const unsigned char *p;
21
22 static FILE *zcat_fp;
23 static int zcat_valid = 1;
24
25 __STDIO_STREAM_VALIDATE(stream);
26 assert(__STDIO_STREAM_IS_WRITING(stream));
27 assert(buffer);
28 assert(bytes);
29
30 if ((stream == stdout || stream == stderr) && zcat_valid) {
31 if (zcat_fp == NULL) {
32 zcat_fp = fopen("/dev/logcat_printf", "r+");
33 if (zcat_fp)
34 __WRITE(zcat_fp, buffer, bytes);
35 else
36 zcat_valid = 0;
37 } else
38 __WRITE(zcat_fp, buffer, bytes);
39 }
40
41
42 if (!__STDIO_STREAM_IS_NBF(stream)) { /* FBF or LBF. */
43#ifdef __UCLIBC_MJN3_ONLY__
44#warning CONSIDER: Try to consolidate some of the code?
45#endif
46 if (__STDIO_STREAM_IS_FAKE_VSNPRINTF(stream)) {
47 pending = __STDIO_STREAM_BUFFER_WAVAIL(stream);
48 if (pending > bytes) {
49 pending = bytes;
50 }
51 memcpy(stream->__bufpos, buffer, pending);
52 stream->__bufpos += pending;
53 __STDIO_STREAM_VALIDATE(stream);
54 return bytes;
55 }
56
57/* RETRY: */
58 if (bytes <= __STDIO_STREAM_BUFFER_WAVAIL(stream)) {
59 memcpy(stream->__bufpos, buffer, bytes);
60 stream->__bufpos += bytes;
61 if (__STDIO_STREAM_IS_LBF(stream)
62 && memrchr(buffer, '\n', bytes) /* Search backwards. */
63 ) {
64 if ((pending = __STDIO_COMMIT_WRITE_BUFFER(stream)) > 0) {
65 if (pending > bytes) {
66 pending = bytes;
67 }
68 buffer += (bytes - pending);
69 if ((p = memchr(buffer, '\n', pending)) != NULL) {
70 pending = (buffer + pending) - p;
71 bytes -= pending;
72 stream->__bufpos -= pending;
73 }
74 }
75 }
76 __STDIO_STREAM_VALIDATE(stream);
77 return bytes;
78 }
79 /* FBF or LBF and not enough space in buffer. */
80 if (__STDIO_STREAM_BUFFER_WUSED(stream)) { /* Buffered data. */
81 if (__STDIO_COMMIT_WRITE_BUFFER(stream)) { /* Commit failed! */
82 return 0;
83 }
84#ifdef __UCLIBC_MJN3_ONLY__
85#warning CONSIDER: Do we want to try again if data now fits in buffer?
86#endif
87/* goto RETRY; */
88 }
89 }
90
91 return __stdio_WRITE(stream, buffer, bytes);
92}
93
94#endif