forked from Vhex-Kernel-Core/fxlibc
100 lines
3.9 KiB
C
100 lines
3.9 KiB
C
#ifndef __BITS_TYPES_FILE_H__
|
|
# define __BITS_TYPES_FILE_H__
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <sys/types.h>
|
|
|
|
#define __FILE_BUF_READ 0
|
|
#define __FILE_BUF_WRITE 1
|
|
|
|
/* The FILE structure is mostly a buffer around kernel-level I/O. Most of the
|
|
work is maintaining that buffer to provide the basic fgetc()/fputc()
|
|
functions, then everything else is built on top of the abstracted stream.
|
|
|
|
The buffer of a FILE can either be in reading or writing mode. When in
|
|
reading mode, the buffer contains pre-fetched data from a previous read that
|
|
hasn't yet been requested by the user. When in writing mode, the buffer
|
|
contains data written by the user which hasn't yet been sent to the kernel.
|
|
|
|
The buffer has the following structure:
|
|
|
|
0 bufpos bufread bufsize
|
|
+--------+---------+---------+
|
|
|xxxxxxxx|rrrrrrrrr|uuuuuuuuu| (When reading)
|
|
+--------+---------+---------+
|
|
|wwwwwwww|uuuuuuuuuuuuuuuuuuu| (When writing)
|
|
+--------+-------------------+
|
|
|
|
x: Data read from file descriptor and returned to user
|
|
r: Data read from file descriptor not yet returned to user
|
|
w: Data written by user not yet sent to file descriptor
|
|
u: Undefined
|
|
|
|
In reading mode, the region [0..bufread) contains data obtained from the
|
|
file. bufpos marks how much has been read, in the sense that [0..bufpos) has
|
|
already been returned to the user while [bufpos..bufread) has not. The offset
|
|
on the underlying file descriptor sits at bufread, so the position reported
|
|
by ftell() is fdpos - bufread + bufpos. The rest of the buffer is undefined.
|
|
|
|
In writing mode, the region [0..bufpos) contains data received through API
|
|
but not yet written to the file descriptor. ftell() reports fdpos + bufpos.
|
|
The rest of the buffer is undefined.
|
|
|
|
The ungetc() function pushes back characters into the buffer; if the FILE is
|
|
unbuffered, then it's made buffered temporarily to hold the characters and
|
|
cleared at the next fflush() or read. The buffer is put in reading mode. For
|
|
this reason, reading functions should test [fp->buf] to check whether there
|
|
is a buffer instead of [fp->bufmode != _IONBF].
|
|
|
|
Many fields in the FILE structure are abstracted away by API calls in layers:
|
|
|
|
1. [fd], [fdpos] and [error] are updated by the primitive functions of
|
|
fileutil.c which essentially wrap kernel I/O (plus clearerr() obviously).
|
|
2. [buf], [bufsize], [bufmode] and [bufowned] are handled by setbuf(),
|
|
setvbuf() and fclose().
|
|
3. [bufpos], [bufread] and [bufdir] are set by primitive read/write functions
|
|
like fgets() or fwrite(), and cleared by fflush().
|
|
4. [readable], [writable], [append] and [text] are set by fopen() and
|
|
freopen(), and used as read-only by the primitive functions of 3.
|
|
|
|
TODO: EOF indicator */
|
|
typedef struct {
|
|
/* File descriptor */
|
|
int fd;
|
|
/* Current position in file, as tracked by the file descriptor (ie. not
|
|
accounting for buffer operations) */
|
|
size_t fdpos;
|
|
|
|
/* Pointer to buffer (NULL if _IONBF) */
|
|
char *buf;
|
|
/* Current position in buffer, water mark of read data in buffer, and
|
|
buffer size; see header comment for details */
|
|
size_t bufpos;
|
|
size_t bufread;
|
|
size_t bufsize;
|
|
/* Number of ungetc()'d characters at the start of buffer data */
|
|
int bufungetc;
|
|
/* Buffering mode; one of _IOFBF, _IOLBF, or _IONBF */
|
|
uint8_t bufmode :2;
|
|
/* We own the buffer and it needs to be freed */
|
|
uint8_t bufowned :1;
|
|
/* __FILE_BUF_READ if the buffer is in reading mode
|
|
__FILE_BUF_WRITE if it's in writing mode
|
|
This mode can only be changed immediately after fflush(). */
|
|
uint8_t bufdir :1;
|
|
|
|
/* Opening flags */
|
|
uint8_t readable :1;
|
|
uint8_t writable :1;
|
|
uint8_t append :1;
|
|
/* Non-zero if text mode, zero if binary mode */
|
|
uint8_t text :1;
|
|
/* EOF indicator */
|
|
uint8_t eof :1;
|
|
/* Error indicator */
|
|
uint8_t error :1;
|
|
} FILE;
|
|
|
|
#endif /*__BITS_TYPES_FILE_H__*/
|