Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
}