size_t attribute_hidden __stdio_WRITE(register FILE *stream, register const unsigned char *buf, size_t bufsize) { size_t todo; ssize_t rv, stodo; __STDIO_STREAM_VALIDATE(stream); assert(stream->__filedes >= -1); assert(__STDIO_STREAM_IS_WRITING(stream)); assert(!__STDIO_STREAM_BUFFER_WUSED(stream)); /* Buffer must be empty. */ todo = bufsize; do { if (todo == 0) { /* Done? */ __STDIO_STREAM_VALIDATE(stream); return bufsize; } stodo = (todo <= SSIZE_MAX) ? todo : SSIZE_MAX; if ((rv = __WRITE(stream, (char *) buf, stodo)) >= 0) { #ifdef __UCLIBC_MJN3_ONLY__ #warning TODO: Make custom stream write return check optional. #endif #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ assert(rv <= stodo); if (rv > stodo) { /* Wrote more than stodo! */ /* abort(); */ } #endif todo -= rv; buf += rv; } else #ifdef __UCLIBC_MJN3_ONLY__ #warning EINTR? #endif /* if (errno != EINTR) */ { __STDIO_STREAM_SET_ERROR(stream); #ifdef __STDIO_BUFFERS if ((stodo = __STDIO_STREAM_BUFFER_SIZE(stream)) != 0) { unsigned char *s; if (stodo > todo) { stodo = todo; } s = stream->__bufstart; do { if (((*s = *buf) == '\n') && __STDIO_STREAM_IS_LBF(stream) ) { break; } ++s; ++buf; } while (--stodo); stream->__bufpos = s; todo -= (s - stream->__bufstart); } #endif /* __STDIO_BUFFERS */ __STDIO_STREAM_VALIDATE(stream); return bufsize - todo; } } while (1); }
int __fputc_unlocked(int c, register FILE *stream) { __STDIO_STREAM_VALIDATE(stream); /* First the fast path. We're good to go if putc macro enabled. */ if (__STDIO_STREAM_CAN_USE_BUFFER_ADD(stream)) { __STDIO_STREAM_BUFFER_ADD(stream, ((unsigned char) c)); return (unsigned char) c; } /* Next quickest... writing and narrow oriented, but macro * disabled and/or buffer is full. */ if (__STDIO_STREAM_IS_NARROW_WRITING(stream) || !__STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_NARROW) ) { if (__STDIO_STREAM_IS_FAKE_VSNPRINTF(stream)) { return (unsigned char) c; } if (__STDIO_STREAM_BUFFER_SIZE(stream)) { /* Do we have a buffer? */ /* The buffer is full and/or the stream is line buffered. */ if (!__STDIO_STREAM_BUFFER_WAVAIL(stream) /* Buffer full? */ && __STDIO_COMMIT_WRITE_BUFFER(stream) /* Commit failed! */ ) { goto BAD; } #ifdef __UCLIBC_MJN3_ONLY__ #warning CONSIDER: Should we fail if the commit fails but we now have room? #endif __STDIO_STREAM_BUFFER_ADD(stream, ((unsigned char) c)); if (IS_STD_STREAM(stream)) { if( __STDIO_COMMIT_WRITE_BUFFER(stream)) { /* Commit failed! */ __STDIO_STREAM_BUFFER_UNADD(stream); /* Undo the write! */ goto BAD; } } else if (__STDIO_STREAM_IS_LBF(stream)) { if ((((unsigned char) c) == '\n') && __STDIO_COMMIT_WRITE_BUFFER(stream)) { /* Commit failed! */ __STDIO_STREAM_BUFFER_UNADD(stream); /* Undo the write! */ goto BAD; } } } else { /* NOTE: Do not try to save space by moving uc to the top of * the file, as that dramaticly increases runtime. */ unsigned char uc = (unsigned char) c; if (! __stdio_WRITE(stream, &uc, 1)) { goto BAD; } } return (unsigned char) c; } BAD: return EOF; }