mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2024-12-28 20:43:38 +01:00
stdio: share the FILE implementation between all versions
This commit is contained in:
parent
f1512125d0
commit
294fda9731
8 changed files with 91 additions and 163 deletions
|
@ -11,7 +11,7 @@ extern "C" {
|
||||||
** parse options, lay out strings, and generate output.
|
** parse options, lay out strings, and generate output.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <bits/types/FILE.h>
|
#include <stdio.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
|
@ -7,9 +7,97 @@ extern "C" {
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
/* Type of FILE handlers. */
|
#define __FILE_BUF_READ 0
|
||||||
#include <bits/types/FILE.h>
|
#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. */
|
||||||
|
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;
|
||||||
|
|
||||||
/* Type of positions within files. We don't have wide-oriented streams. */
|
/* Type of positions within files. We don't have wide-oriented streams. */
|
||||||
typedef size_t fpos_t;
|
typedef size_t fpos_t;
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
#ifndef __BITS_TYPES_FILE_H__
|
|
||||||
# define __BITS_TYPES_FILE_H__
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
} FILE;
|
|
||||||
|
|
||||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
|
@ -1,7 +0,0 @@
|
||||||
#ifndef __BITS_TYPES_FILE_H__
|
|
||||||
# define __BITS_TYPES_FILE_H__
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
} FILE;
|
|
||||||
|
|
||||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
|
@ -1,99 +0,0 @@
|
||||||
#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__*/
|
|
|
@ -1,13 +0,0 @@
|
||||||
#ifndef __BITS_TYPES_FILE_H__
|
|
||||||
# define __BITS_TYPES_FILE_H__
|
|
||||||
|
|
||||||
// opaque definition of the _IO_FILE
|
|
||||||
struct _IO_FILE;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** The opaque type of streams.
|
|
||||||
** This is the definition used elsewhere.
|
|
||||||
*/
|
|
||||||
typedef struct _IO_FILE FILE;
|
|
||||||
|
|
||||||
#endif /*__BITS_TYPES_FILE_H__*/
|
|
|
@ -1,8 +0,0 @@
|
||||||
#ifndef __BITS_TYPES___FILE_H__
|
|
||||||
# define ___BITS_TYPES___FILE_H__
|
|
||||||
|
|
||||||
// define opaque definition of the FILE type
|
|
||||||
struct _IO_FILE;
|
|
||||||
typedef struct _IO_FILE __FILE;
|
|
||||||
|
|
||||||
#endif /*__BITS_TYPES___FILE_H__*/
|
|
|
@ -1,26 +0,0 @@
|
||||||
#ifndef __BITS_TYPES_STRUCT_FILE_H__
|
|
||||||
# define __BITS_TYPES_STRUCT_FILE_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
//---
|
|
||||||
// TODO: VFS abstraction ? or ABI-spesific abstraction ?
|
|
||||||
//---
|
|
||||||
|
|
||||||
|
|
||||||
// Define _IO_FILE
|
|
||||||
// TODO: add open flags
|
|
||||||
// TODO: add file descriptor ?
|
|
||||||
// TODO: update me !
|
|
||||||
struct _IO_FILE
|
|
||||||
{
|
|
||||||
off_t cursor;
|
|
||||||
int permission;
|
|
||||||
void *file_op;
|
|
||||||
void *private;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /*__BITS_TYPES_STRUCT_FILE_H__*/
|
|
Loading…
Reference in a new issue