Ejemplo n.º 1
0
void __libc_init_stdio(void)
{
	stdin  = fdopen(0, NULL);
	stdout = fdopen(1, NULL);
	stderr = fdopen(2, NULL);
	stdio_pvt(stderr)->bufmode = _IONBF;
}
Ejemplo n.º 2
0
/*@
	requires file == &(stdio_pvt(file)->pub);
	requires valid_IO_file_pvt(stdio_pvt(file));
	requires -128 <= c <= 127;
	
	behavior fail:
		assumes stdio_pvt(file)->obytes || stdio_pvt(file)->data <= stdio_pvt(file)->buf;
		assigns \nothing;
		ensures \result == EOF;

	behavior success:
		assumes stdio_pvt(file)->obytes == 0 && !(stdio_pvt(file)->data <= stdio_pvt(file)->buf);
		//assumes \valid(stdio_pvt(file)->data - 1);
		assigns stdio_pvt(file)->ibytes, stdio_pvt(file)->data, *(\at(stdio_pvt(file)->data, Pre)-1); 
		ensures stdio_pvt(file)->ibytes == \at(stdio_pvt(file)->ibytes, Pre) + 1;
		ensures stdio_pvt(file)->data == \at(stdio_pvt(file)->data, Pre) -1;
		ensures *(stdio_pvt(file)->data) == c;
		ensures \result == c;

	complete behaviors;
	disjoint behaviors;
@*/
int ungetc(int c, FILE *file)
{
	struct _IO_file_pvt *f = stdio_pvt(file);
	
	if (f->obytes || f->data <= f->buf)
		return EOF;

	*(--f->data) = c;
	f->ibytes++;

	return c;
}
Ejemplo n.º 3
0
int fgetc_orig(FILE *file)
{
	struct _IO_file_pvt *f = stdio_pvt(file);
	unsigned char ch;

	if (__likely(f->ibytes)) {
		f->ibytes--;
		return (unsigned char) *f->data++;
	} else {
		return _fread(&ch, 1, file) == 1 ? ch : EOF;
	}
}
Ejemplo n.º 4
0
off_t ftell(FILE *file)
{
#ifdef KLIBC_STREAMS_ORIG
	struct _IO_file_pvt *f = stdio_pvt(file);
	off_t pos = lseek(f->pub._IO_fileno, 0, SEEK_CUR);

	if (pos >= 0)
		pos += (int)f->obytes - (int)f->ibytes;

	return pos;
#else
	return lseek(file->_IO_fileno, 0, SEEK_CUR);
#endif
}
Ejemplo n.º 5
0
/*@
	requires file == &(stdio_pvt(file)->pub);
	requires valid_IO_file_pvt(stdio_pvt(file));
	assigns stdio_pvt(file)->next->prev, stdio_pvt(file)->prev->next,
		stdio_pvt(file)->ibytes, stdio_pvt(file)->pub._IO_eof, stdio_pvt(file)->pub._IO_error, stdio_pvt(file)->obytes, errno;
 	ensures \result == 0 || \result -1;
 @*/
int fclose(FILE *file)
{
	struct _IO_file_pvt *f = stdio_pvt(file);
	int rv;

	fflush(file);

	rv = close(f->pub._IO_fileno);

	/* Remove from linked list */
	f->next->prev = f->prev;
	f->prev->next = f->next;

	free(f);
	return rv;
}
Ejemplo n.º 6
0
size_t _fwrite(const void *buf, size_t count, FILE *file)
{
	struct _IO_file_pvt *f = stdio_pvt(file);
	size_t bytes = 0;
	size_t pf_len, pu_len;
	const char *p = buf;
	const char *q;

	/* We divide the data into two chunks, flushed (pf)
	   and unflushed (pu) depending on buffering mode
	   and contents. */

	switch (f->bufmode) {
	case _IOFBF:
		pf_len = 0;
		break;

	case _IOLBF:
		q = memrchr(p, '\n', count);
		pf_len = q ? q - p + 1 : 0;
		break;

	case _IONBF:
	default:
		pf_len = count;
		break;
	}

	if (pf_len) {
		bytes = fwrite_noflush(p, pf_len, f);
		p += bytes;
		if (__fflush(f) || bytes != pf_len)
			return bytes;
	}

	pu_len = count - pf_len;
	if (pu_len)
		bytes += fwrite_noflush(p, pu_len, f);

	return bytes;
}
Ejemplo n.º 7
0
/*@
	requires file == \null || file == &(stdio_pvt(file)->pub);
	requires valid_IO_file_pvt(stdio_pvt(file));
	assigns stdio_pvt(file)->ibytes, stdio_pvt(file)->pub._IO_eof, stdio_pvt(file)->pub._IO_error, stdio_pvt(file)->obytes, errno;
@*/
int fflush(FILE *file)
{
	struct _IO_file_pvt *f;

	if (__likely(file)) {
		f = stdio_pvt(file);
		return __fflush(f);
	} else {
		int err = 0;

		/*@
			loop invariant valid_IO_file_pvt(f);
			loop invariant f != &__stdio_headnode;
			loop assigns f, err;
		*/
		for (f = __stdio_headnode.next;
		     f != &__stdio_headnode;
		     f = f->next) {
			if (f->obytes)
				err |= __fflush(f);
		}
		return err;
	}
}
Ejemplo n.º 8
0
/*@
	requires 0 <= count;
	requires \separated(((char*)buf)+(0..count-1), stdio_pvt(file)->next, stdio_pvt(file)->prev, stdio_pvt(file)->buf+(0..(stdio_pvt(file)->bufsiz+32-1)));
	requires file == &(stdio_pvt(file)->pub);
	requires valid_IO_file_pvt(stdio_pvt(file));
	requires \valid(((char*)buf)+(0..count-1));
@*/
size_t _fread(void *buf, size_t count, FILE *file)
{
	struct _IO_file_pvt *f = stdio_pvt(file);
	size_t bytes = 0;
	size_t nb;
	char *p = buf;
	char *rdptr;
	ssize_t rv;
	bool bypass;

	if (!count)
		return 0;

	if (f->obytes)		/* User error! */
		__fflush(f);

	/*@
		loop invariant \base_addr(p) == \base_addr(buf);
		loop invariant 0 <= bytes;
		loop invariant \base_addr(rdptr) == \base_addr(f->data);
		loop invariant f->data <= rdptr <= f->data + f->bufsiz + 32; 
		loop invariant (char*)buf <= p <= (char*)buf + \at(count, Pre);
		loop invariant 0 <= count;
		loop assigns rv, bypass, rdptr, nb, f->pub._IO_error, f->pub._IO_eof, p, bytes, count, f->ibytes, f->data;
		loop variant count;
	@*/
	while (count) {
		while (f->ibytes == 0) {
			/*
			 * The buffer is empty, we have to read
			 */
			bypass = (count >= f->bufsiz);
			if (bypass) {
				/* Large read, bypass buffer */
				rdptr = p;
				nb = count;
			} else {
				rdptr = f->buf + _IO_UNGET_SLOP;
				nb = f->bufsiz;
			}

			rv = read(f->pub._IO_fileno, rdptr, nb);
			if (rv == -1) {
				if (errno == EINTR || errno == EAGAIN)
					continue;
				f->pub._IO_error = true;
				return bytes;
			} else if (rv == 0) {
				f->pub._IO_eof = true;
				return bytes;


			}

			if (bypass) {
				p += rv;
				bytes += rv;
				count -= rv;
			} else {
				f->ibytes = rv;
				f->data = rdptr;
			}

			if (!count)
				return bytes;
		}

		/* If we get here, the buffer is non-empty */
		nb = f->ibytes;
		nb = (count < nb) ? count : nb;
		if (nb) {
			memcpy(p, f->data, nb);
			p += nb;
			bytes += nb;
			count -= nb;
			f->data += nb;
			f->ibytes -= nb;
		}
	}
	return bytes;
}