Ejemplo n.º 1
0
size_t __stdio_READ(register FILE *stream,
					unsigned char *buf, size_t bufsize)
{
	ssize_t rv = 0;

	__STDIO_STREAM_VALIDATE(stream);
	assert(stream->__filedes >= -1);
	assert(__STDIO_STREAM_IS_READING(stream));
	assert(!__STDIO_STREAM_BUFFER_RAVAIL(stream)); /* Buffer must be empty. */
	assert(!(stream->__modeflags & __FLAG_UNGOT));
	assert(bufsize);

	if (!__FEOF_UNLOCKED(stream)) {
		if (bufsize > SSIZE_MAX) {
			bufsize = SSIZE_MAX;
		}

#ifdef __UCLIBC_MJN3_ONLY__
#warning EINTR?
#endif
/* 	RETRY: */
		if ((rv = __READ(stream, buf, bufsize)) <= 0) {
			if (rv == 0) {
				__STDIO_STREAM_SET_EOF(stream);
			} else {
/* 				if (errno == EINTR) goto RETRY; */
				__STDIO_STREAM_SET_ERROR(stream);
				rv = 0;
			}
#ifdef __UCLIBC_MJN3_ONLY__
#warning TODO: Make custom stream read return check optional.
#endif
#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
		} else {
			assert(rv <= bufsize);
			if (rv > bufsize) {	/* Read more than bufsize! */
				abort();
			}
#endif
		}
	}

	return rv;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
int fflush_unlocked(register FILE *stream)
{
#ifdef __STDIO_BUFFERS

	int retval = 0;
#ifdef __UCLIBC_MJN3_ONLY__
#warning REMINDER: should probably define a modeflags type
#endif
	unsigned short bufmask = __FLAG_LBF;

#ifndef NDEBUG
	if ((stream != NULL) && (stream != (FILE *) &_stdio_openlist)) {
		__STDIO_STREAM_VALIDATE(stream); /* debugging only */
	}
#endif

	if (stream == (FILE *) &_stdio_openlist) { /* Flush all lbf streams. */
		stream = NULL;
		bufmask = 0;
	}

	if (!stream) {				/* Flush all (lbf) writing streams. */

		__STDIO_OPENLIST_INC_USE;

		__STDIO_THREADLOCK_OPENLIST_ADD;
		stream = _stdio_openlist;
		__STDIO_THREADUNLOCK_OPENLIST_ADD;

		while(stream) {
			/* We only care about currently writing streams and do not want to
			 * block trying to obtain mutexes on non-writing streams. */
#warning fix for nonatomic
#warning unnecessary check if no threads
			if (__STDIO_STREAM_IS_WRITING(stream)) { /* ONLY IF ATOMIC!!! */
				__MY_STDIO_THREADLOCK(stream);
				/* Need to check again once we have the lock. */
				if (!(((stream->__modeflags | bufmask)
					   ^ (__FLAG_WRITING|__FLAG_LBF)
					   ) & (__FLAG_WRITING|__MASK_BUFMODE))
					) {
					if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
						__STDIO_STREAM_DISABLE_PUTC(stream);
						__STDIO_STREAM_CLEAR_WRITING(stream);
					} else {
						retval = EOF;
					}
				}
				__MY_STDIO_THREADUNLOCK(stream);
			}
			stream = stream->__nextopen;
		}

		__STDIO_OPENLIST_DEC_USE;

	} else if (__STDIO_STREAM_IS_WRITING(stream)) {
		if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
			__STDIO_STREAM_DISABLE_PUTC(stream);
			__STDIO_STREAM_CLEAR_WRITING(stream);
		} else {
			retval = EOF;
		}
	}
#if 0
	else if (stream->__modeflags & (__MASK_READING|__FLAG_READONLY)) {
		/* ANSI/ISO says behavior in this case is undefined but also says you
		 * shouldn't flush a stream you were reading from.  As usual, glibc
		 * caters to broken programs and simply ignores this. */
		__UNDEFINED_OR_NONPORTABLE;
		__STDIO_STREAM_SET_ERROR(stream);
		__set_errno(EBADF);
		retval = EOF;
	}
#endif

#ifndef NDEBUG
	if ((stream != NULL) && (stream != (FILE *) &_stdio_openlist)) {
		__STDIO_STREAM_VALIDATE(stream); /* debugging only */
	}
#endif

	return retval;

#else  /* __STDIO_BUFFERS --------------------------------------- */

#ifndef NDEBUG
	if ((stream != NULL)
#ifdef __STDIO_HAS_OPENLIST
		&& (stream != (FILE *) &_stdio_openlist)
#endif
		) {
		__STDIO_STREAM_VALIDATE(stream); /* debugging only */
	}
#endif

#if 0
	if (stream && (stream->__modeflags & (__MASK_READING|__FLAG_READONLY))) {
		/* ANSI/ISO says behavior in this case is undefined but also says you
		 * shouldn't flush a stream you were reading from.  As usual, glibc
		 * caters to broken programs and simply ignores this. */
		__UNDEFINED_OR_NONPORTABLE;
		__STDIO_STREAM_SET_ERROR(stream);
		__set_errno(EBADF);
		return EOF;
	}
#endif

	return 0;
#endif /* __STDIO_BUFFERS */
}