mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2024-12-28 04:23:38 +01:00
stdio: FILE barebones with buffering model (WIP)
This commit is contained in:
parent
b53078776d
commit
51528170bb
11 changed files with 349 additions and 107 deletions
|
@ -120,6 +120,8 @@ set(SOURCES
|
||||||
# stdio
|
# stdio
|
||||||
src/libc/stdio/asprintf.c
|
src/libc/stdio/asprintf.c
|
||||||
src/libc/stdio/dprintf.c
|
src/libc/stdio/dprintf.c
|
||||||
|
src/libc/stdio/fflush.c
|
||||||
|
src/libc/stdio/fileutil.c
|
||||||
src/libc/stdio/fprintf.c
|
src/libc/stdio/fprintf.c
|
||||||
src/libc/stdio/printf.c
|
src/libc/stdio/printf.c
|
||||||
src/libc/stdio/printf/format_fixed.c
|
src/libc/stdio/printf/format_fixed.c
|
||||||
|
@ -129,6 +131,9 @@ set(SOURCES
|
||||||
src/libc/stdio/printf/util.c
|
src/libc/stdio/printf/util.c
|
||||||
src/libc/stdio/putc.c
|
src/libc/stdio/putc.c
|
||||||
src/libc/stdio/puts.c
|
src/libc/stdio/puts.c
|
||||||
|
src/libc/stdio/remove.c
|
||||||
|
src/libc/stdio/setbuf.c
|
||||||
|
src/libc/stdio/setvbuf.c
|
||||||
src/libc/stdio/snprintf.c
|
src/libc/stdio/snprintf.c
|
||||||
src/libc/stdio/sprintf.c
|
src/libc/stdio/sprintf.c
|
||||||
src/libc/stdio/vasprintf.c
|
src/libc/stdio/vasprintf.c
|
||||||
|
|
213
STATUS
213
STATUS
|
@ -31,51 +31,49 @@ TODO: Function/symbol/macro is not implemented/defined
|
||||||
BDEPS(...): Function/symbol/macro needs ... to build
|
BDEPS(...): Function/symbol/macro needs ... to build
|
||||||
LDEPS(...): Function/symbol/macro needs ... to link
|
LDEPS(...): Function/symbol/macro needs ... to link
|
||||||
TEST: Function/symbol/macro needs to be tested
|
TEST: Function/symbol/macro needs to be tested
|
||||||
DONE: Function/symbol/macro is defined, builds, links, and is tested
|
-: Function/symbol/macro is defined, builds, links, and is tested
|
||||||
|
|
||||||
7.2 <assert.h>
|
7.2 <assert.h>
|
||||||
! 7.2.1 assert: LDEPS(fprintf,stderr)
|
7.2.1 assert LDEPS(fprintf,stderr)
|
||||||
|
|
||||||
7.3 <complex.h> => OpenLibm
|
7.3 <complex.h> => OpenLibm
|
||||||
|
|
||||||
7.4 <ctype.h>
|
7.4 <ctype.h>
|
||||||
7.4.1 is*: DONE
|
7.4.1 is* -
|
||||||
7.4.2 to*: DONE
|
7.4.2 to* -
|
||||||
|
|
||||||
7.5 <errno.h>
|
7.5 <errno.h>
|
||||||
7.5.2 EDOM EILSEQ ERANGE: DONE
|
7.5.2 EDOM, EILSEQ, ERANGE -
|
||||||
|
|
||||||
7.6 <fenv.h> => OpenLibm
|
7.6 <fenv.h> => OpenLibm
|
||||||
|
|
||||||
7.7 <float.h> => GCC
|
7.7 <float.h> => GCC
|
||||||
|
|
||||||
7.8 <inttypes.h>
|
7.8 <inttypes.h>
|
||||||
! 7.8.1 PRI* macros: LDEPS(*printf)
|
7.8.1 PRI* macros -
|
||||||
! 7.8.1 SCN* macros: LDEPS(*scanf)
|
7.8.1 SCN* macros -
|
||||||
7.8.2.1 imaxabs: DONE
|
7.8.2.1 imaxabs -
|
||||||
7.8.2.2 imaxdiv: DONE
|
7.8.2.2 imaxdiv -
|
||||||
7.8.2.3 strtoimax strtoumax: DONE
|
7.8.2.3 strtoimax, strtoumax -
|
||||||
! 7.8.2.4 wcstoimax wcstoumax: TODO
|
7.8.2.4 wcstoimax, wcstoumax TODO
|
||||||
|
|
||||||
7.9 <iso646.h> => GCC
|
7.9 <iso646.h> => GCC
|
||||||
|
|
||||||
7.10 <limits.h> => GCC
|
7.10 <limits.h> => GCC
|
||||||
|
|
||||||
7.11 <locale.h>
|
7.11 <locale.h>
|
||||||
! 7.11.1 setlocale: TEST
|
7.11.1 setlocale TEST
|
||||||
! 7.11.2 localeconv: TEST
|
7.11.2 localeconv TEST
|
||||||
|
|
||||||
7.12 <math.h> => OpenLibm
|
7.12 <math.h> => OpenLibm
|
||||||
|
|
||||||
7.13 <setjmp.h>
|
7.13 <setjmp.h>
|
||||||
7.13.1 setjmp: DONE
|
7.13.1 setjmp -
|
||||||
7.13.2 longjmp: DONE
|
7.13.2 longjmp -
|
||||||
|
|
||||||
7.14 <signal.h>
|
7.14 <signal.h>
|
||||||
7.14 sig_atomic_t SIG_DFL SIG_ERR SIG_IGN: DONE
|
7.14.1.1 signal -
|
||||||
7.14 SIGABRT SIGFPE SIGILL SIGINT SIGSEGV SIGTERM: DONE
|
7.14.1.2 raise -
|
||||||
7.14.1.1 signal: DONE
|
|
||||||
7.14.1.2 raise: DONE
|
|
||||||
|
|
||||||
7.15 <stdarg.h> => GCC
|
7.15 <stdarg.h> => GCC
|
||||||
|
|
||||||
|
@ -86,93 +84,114 @@ DONE: Function/symbol/macro is defined, builds, links, and is tested
|
||||||
7.18 <stdint.h> => GCC
|
7.18 <stdint.h> => GCC
|
||||||
|
|
||||||
7.19 <stdio.h>
|
7.19 <stdio.h>
|
||||||
7.19.1 Introduction: TEST
|
7.19.1 Introduction TEST
|
||||||
TODO: Handle wide-oriented streams? (see notes)
|
No wide-oriented streams (see notes)
|
||||||
! 7.19.4 Operations on files: TODO
|
7.19.4.1 remove TEST
|
||||||
! 7.19.5 File access functions: TODO
|
7.19.4.2 rename TODO
|
||||||
! 7.19.6 Formatted input/output functions: TODO
|
7.19.4.3 tmpfile TODO
|
||||||
! 7.19.7 Character input/output functions: TODO
|
7.19.4.4 tmpnam TODO
|
||||||
! 7.19.8 Direct input/output functions: TODO
|
7.19.5.1 fclose TODO
|
||||||
! 7.19.9 File positioning functions: TODO
|
7.19.5.2 fflush TODO
|
||||||
! 7.19.10 Error-handling functions: TODO
|
7.19.5.3 fopen TODO
|
||||||
|
7.19.5.4 freopen TODO
|
||||||
|
7.19.5.5 setbuf TODO
|
||||||
|
7.19.5.6 setvbuf TODO
|
||||||
|
7.19.6.1 fprintf LDEPS(fwrite)
|
||||||
|
7.19.6.2 fscanf TODO
|
||||||
|
7.19.6.3 printf LDEPS(fwrite, stdout)
|
||||||
|
7.19.6.4 scanf TODO
|
||||||
|
7.19.6.5 snprintf -
|
||||||
|
7.19.6.6 sprintf -
|
||||||
|
7.19.6.7 sscanf TODO
|
||||||
|
7.19.6.8 vfprintf LDEPS(fwrite)
|
||||||
|
7.19.6.9 vfscanf TODO
|
||||||
|
7.19.6.10 vprintf LDEPS(fwrite, stdout)
|
||||||
|
7.19.6.11 vscanf TODO
|
||||||
|
7.19.6.12 vsnprintf -
|
||||||
|
7.19.6.13 vsprintf -
|
||||||
|
7.19.6.14 vsscanf TODO
|
||||||
|
(EXT) asprintf -
|
||||||
|
(EXT) vasprintf -
|
||||||
|
(EXT) dprintf TEST
|
||||||
|
(EXT) vdprintf TEST
|
||||||
|
7.19.7 Character input/output TODO
|
||||||
|
7.19.8 Direct input/output TODO
|
||||||
|
7.19.9 File positioning TODO
|
||||||
|
7.19.10 Error-handling TODO
|
||||||
|
|
||||||
7.20 <stdlib.h>
|
7.20 <stdlib.h>
|
||||||
7.20 RAND_MAX: DONE
|
7.20 MB_CUR_MAX TODO
|
||||||
! 7.20 MB_CUR_MAX: TODO
|
7.20.1.1 atof -
|
||||||
7.20.1.1 atof: DONE
|
7.20.1.2 atoi, atol, atoll -
|
||||||
7.20.1.2 atoi, atol, atoll: DONE
|
7.20.1.3 strtod, strtof, strtold -
|
||||||
7.20.1.3 strtod, strtof, strtold: DONE
|
7.20.1.4 strtol, strtoul -
|
||||||
7.20.1.4 strtol, strtoul, strtoll, strtoull: DONE
|
7.20.1.4 strtoll, strtoull -
|
||||||
7.20.2.1 rand: DONE
|
7.20.2.1 rand -
|
||||||
7.20.2.2 srand: DONE
|
7.20.2.2 srand -
|
||||||
7.20.3.1 calloc: DONE
|
7.20.3.1 calloc -
|
||||||
7.20.3.2 free: DONE (at least gint)
|
7.20.3.2 free - (gint)
|
||||||
7.20.3.3 malloc: DONE (at least gint)
|
7.20.3.3 malloc - (gint)
|
||||||
7.20.3.4 realloc: DONE (at least gint)
|
7.20.3.4 realloc - (gint)
|
||||||
7.20.4.1 abort: DONE
|
7.20.4.1 abort - (stream flushing/closing/etc?)
|
||||||
! 7.20.4.2 atexit: TODO
|
7.20.4.2 atexit TODO
|
||||||
7.20.4.3 exit: DONE (missing stream flushing/closing/etc)
|
7.20.4.3 exit - (stream flushing/closing/etc?)
|
||||||
7.20.4.4 _Exit: DONE (gint only)
|
7.20.4.4 _Exit - (gint)
|
||||||
! 7.20.4.5 getenv: TODO
|
7.20.4.5 getenv TODO
|
||||||
! 7.20.4.6 system: TODO
|
7.20.4.6 system TODO
|
||||||
! 7.20.5.1 bsearch: TODO
|
7.20.5.1 bsearch TODO
|
||||||
! 7.20.5.2 qsort: TEST
|
7.20.5.2 qsort TEST
|
||||||
7.20.6.1 abs, labs, llabs: DONE
|
7.20.6.1 abs, labs, llabs -
|
||||||
7.20.6.2 div, ldiv, lldiv: DONE
|
7.20.6.2 div, ldiv, lldiv -
|
||||||
! 7.20.7 Multibyte/wide character conversion functions: TODO
|
7.20.7 Multibyte/wide char conv TODO
|
||||||
! 7.20.8 Multibyte/wide string conversion functions: TODO
|
7.20.8 Multibyte/wide string conv TODO
|
||||||
|
|
||||||
7.21 <string.h>
|
7.21 <string.h>
|
||||||
7.21.2.1 memcpy: DONE
|
7.21.2.1 memcpy -
|
||||||
7.21.2.2 memmove: DONE (Unoptimized: byte-by-byte)
|
7.21.2.2 memmove - (Unoptimized: byte-by-byte)
|
||||||
7.21.2.3 strcpy: DONE
|
7.21.2.3 strcpy -
|
||||||
7.21.2.4 strncpy: DONE
|
7.21.2.4 strncpy -
|
||||||
7.21.3.1 strcat: DONE
|
7.21.3.1 strcat -
|
||||||
7.21.3.2 strncat: DONE
|
7.21.3.2 strncat -
|
||||||
7.21.4.1 memcmp: DONE
|
7.21.4.1 memcmp -
|
||||||
7.21.4.2 strcmp: DONE
|
7.21.4.2 strcmp -
|
||||||
7.21.4.3 strcoll: DONE
|
7.21.4.3 strcoll -
|
||||||
7.21.4.4 strncmp: DONE
|
7.21.4.4 strncmp -
|
||||||
7.21.4.5 strxfrm: DONE
|
7.21.4.5 strxfrm -
|
||||||
7.21.5.1 memchr: DONE
|
7.21.5.1 memchr -
|
||||||
7.21.5.2 strchr: DONE
|
7.21.5.2 strchr -
|
||||||
7.21.5.3 strcspn: DONE
|
7.21.5.3 strcspn -
|
||||||
7.21.5.4 strpbrk: DONE
|
7.21.5.4 strpbrk -
|
||||||
7.21.5.5 strrchr: DONE
|
7.21.5.5 strrchr -
|
||||||
7.21.5.6 strspn: DONE
|
7.21.5.6 strspn -
|
||||||
7.21.5.7 strstr: DONE
|
7.21.5.7 strstr -
|
||||||
7.21.5.8 strtok: DONE
|
7.21.5.8 strtok -
|
||||||
7.21.6.1 memset: DONE
|
7.21.6.1 memset -
|
||||||
7.21.6.2 strerror: DONE
|
7.21.6.2 strerror -
|
||||||
7.21.6.3 strlen: DONE
|
7.21.6.3 strlen -
|
||||||
Extensions:
|
(EXT) strnlen -
|
||||||
- strnlen: DONE
|
(EXT) strchrnul -
|
||||||
- strchrnul: DONE
|
(EXT) strcasestr -
|
||||||
- strcasestr: DONE
|
(EXT) strcasecmp -
|
||||||
- strcasecmp: DONE
|
(EXT) strncasecmp -
|
||||||
- strncasecmp: DONE
|
(EXT) strdup -
|
||||||
- strdup: DONE
|
(EXT) strndup -
|
||||||
- strndup: DONE
|
|
||||||
|
|
||||||
7.22 <tgmath.h> => GCC
|
7.22 <tgmath.h> => GCC
|
||||||
|
|
||||||
7.23 <time.h>
|
7.23 <time.h>
|
||||||
7.23.1 Components of time: DONE
|
7.23.2.1 clock -
|
||||||
7.23.2.1 clock: DONE
|
7.23.2.2 difftime -
|
||||||
7.23.2.2 difftime: DONE
|
7.23.2.3 mktime - (DST flag ignored)
|
||||||
7.23.2.3 mktime: DONE (DST flag ignored)
|
7.23.2.4 time -
|
||||||
7.23.2.4 time: DONE
|
7.23.3.1 asctime -
|
||||||
7.23.3.1 asctime: DONE
|
7.23.3.2 ctime -
|
||||||
7.23.3.2 ctime: DONE
|
7.23.3.3 gmtime -
|
||||||
7.23.3.3 gmtime: DONE
|
7.23.3.4 localtime - (No timezones; same as gmtime)
|
||||||
7.23.3.4 localtime: DONE (No timezones; same as gmtime)
|
7.23.3.5 strftime - (No %g, %G, %U, %V, %W, %z, %Z)
|
||||||
7.23.3.5 strftime: DONE (No %g/%G/%U/%V/%W; timezones %z/%Z empty)
|
|
||||||
|
|
||||||
7.24 <wchar.h>
|
7.24 <wchar.h> TODO (not a priority)
|
||||||
TODO (not a priority)
|
|
||||||
|
|
||||||
7.25 <wctype.h>
|
7.25 <wctype.h> TODO (not a priority)
|
||||||
TODO (not a priority)
|
|
||||||
|
|
||||||
# Supporting locales
|
# Supporting locales
|
||||||
|
|
||||||
|
@ -188,7 +207,7 @@ What if we wanted to support more locales?
|
||||||
|
|
||||||
# Supporting text and binary files (newline translation)
|
# Supporting text and binary files (newline translation)
|
||||||
|
|
||||||
Because of 7.19.2%1,223 we don't need to support newline translation.
|
Because of 7.19.2§1.223 we don't need to support newline translation.
|
||||||
|
|
||||||
# Support wide-oriented streams
|
# Support wide-oriented streams
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ extern "C" {
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
/* Hide by default in C++ (7.8.1§1.181) */
|
/* Hide by default in C++ (7.8.1§1.182) */
|
||||||
#if !defined __cplusplus || defined __STDC_FORMAT_MACROS
|
#if !defined __cplusplus || defined __STDC_FORMAT_MACROS
|
||||||
|
|
||||||
/* Printing signed fixed-width types, decimal */
|
/* Printing signed fixed-width types, decimal */
|
||||||
|
|
|
@ -20,8 +20,7 @@ typedef size_t fpos_t;
|
||||||
#define _IONBF 2
|
#define _IONBF 2
|
||||||
|
|
||||||
/* Some buffer size for file buffering. */
|
/* Some buffer size for file buffering. */
|
||||||
/* TODO: We might want a larger BUFSIZ than 256 on fx-CG 50. */
|
#define BUFSIZ 512
|
||||||
#define BUFSIZ 256
|
|
||||||
|
|
||||||
/* End-of-file marker. */
|
/* End-of-file marker. */
|
||||||
#define EOF ((int)(-1))
|
#define EOF ((int)(-1))
|
||||||
|
@ -55,6 +54,28 @@ extern FILE *stderr;
|
||||||
#define stdout stdout
|
#define stdout stdout
|
||||||
#define stderr stderr
|
#define stderr stderr
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Operations on files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Remove a file from the filesystem.
|
||||||
|
In gint, the file must not be open (open files' names are not tracked). */
|
||||||
|
extern int remove(char const *__filename);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** File access functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Flush any written data in the FILE's internal buffer. */
|
||||||
|
extern int fflush(FILE *__fp);
|
||||||
|
|
||||||
|
/* Use __buf as a buffer (of size BUFSIZ) for access to __fp. */
|
||||||
|
extern void setbuf(FILE * __restrict__ __fp, char * __restrict__ __buf);
|
||||||
|
|
||||||
|
/* Changer the buffering mode and buffer address for __fp. */
|
||||||
|
extern int setvbuf(FILE * __restrict__ __fp, char * __restrict__ __buf,
|
||||||
|
int __mode, size_t __size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Formatted input/output functions.
|
** Formatted input/output functions.
|
||||||
**
|
**
|
||||||
|
|
|
@ -2,16 +2,77 @@
|
||||||
# define __BITS_TYPES_FILE_H__
|
# define __BITS_TYPES_FILE_H__
|
||||||
|
|
||||||
#include <stddef.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. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* BFile handler */
|
/* File descriptor */
|
||||||
int fd;
|
int fd;
|
||||||
/* Current position in file */
|
/* Current position in file, as tracked by the file descriptor (ie. not
|
||||||
size_t pos;
|
accounting for buffer operations) */
|
||||||
/* Buffering mode */
|
size_t fdpos;
|
||||||
// TODO
|
|
||||||
/* Opening mode */
|
/* Pointer to buffer (NULL if _IONBF) */
|
||||||
// TODO
|
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;
|
||||||
|
/* 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 when bufpos=0, ie. just 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;
|
} FILE;
|
||||||
|
|
||||||
#endif /*__BITS_TYPES_FILE_H__*/
|
#endif /*__BITS_TYPES_FILE_H__*/
|
||||||
|
|
33
src/libc/stdio/fflush.c
Normal file
33
src/libc/stdio/fflush.c
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "fileutil.h"
|
||||||
|
|
||||||
|
int fflush(FILE *fp)
|
||||||
|
{
|
||||||
|
// TODO: fflush(NULL) should flush "all" files (do we track them?)
|
||||||
|
if(!fp) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
if(!fp->buf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
/* In reading mode, reset the file offset */
|
||||||
|
if(fp->bufmode == __FILE_BUF_READ && fp->bufpos < fp->bufread) {
|
||||||
|
fp->fdpos = fp->fdpos - fp->bufread + fp->bufpos;
|
||||||
|
lseek(fp->fd, fp->fdpos, SEEK_SET);
|
||||||
|
fp->bufpos = 0;
|
||||||
|
fp->bufread = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In writing mode, write pending data */
|
||||||
|
else if(fp->bufmode == __FILE_BUF_WRITE && fp->bufpos > 0) {
|
||||||
|
rc = __fp_write(fp, fp->buf, fp->bufpos);
|
||||||
|
fp->bufpos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
19
src/libc/stdio/fileutil.c
Normal file
19
src/libc/stdio/fileutil.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "fileutil.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int __fp_write(FILE *fp, void const *data, size_t size)
|
||||||
|
{
|
||||||
|
if(!fp)
|
||||||
|
return EOF;
|
||||||
|
|
||||||
|
ssize_t rc = write(fp->fd, data, size);
|
||||||
|
|
||||||
|
if(rc < 0) {
|
||||||
|
fp->error = 1;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fp->fdpos += rc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
18
src/libc/stdio/fileutil.h
Normal file
18
src/libc/stdio/fileutil.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef __FILEUTIL_H__
|
||||||
|
# define __FILEUTIL_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* Write data to a file descriptor; updates the fdpos and sets the error
|
||||||
|
indicator. Returns 0 on success, EOF on error. */
|
||||||
|
int __fp_write(FILE *fp, void const *data, size_t size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__FILEUTIL_H__*/
|
19
src/libc/stdio/remove.c
Normal file
19
src/libc/stdio/remove.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
int remove(char const *filename)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
int rc = stat(filename, &st);
|
||||||
|
if(rc < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(S_ISDIR(st.st_mode)) {
|
||||||
|
return rmdir(filename);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return unlink(filename);
|
||||||
|
}
|
||||||
|
}
|
11
src/libc/stdio/setbuf.c
Normal file
11
src/libc/stdio/setbuf.c
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void setbuf(FILE * restrict fp, char * restrict buf)
|
||||||
|
{
|
||||||
|
if(buf) {
|
||||||
|
setvbuf(fp, buf, _IOFBF, BUFSIZ);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setvbuf(fp, buf, _IONBF, 0);
|
||||||
|
}
|
||||||
|
}
|
36
src/libc/stdio/setvbuf.c
Normal file
36
src/libc/stdio/setvbuf.c
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
int setvbuf(FILE * restrict fp, char * restrict buf, int mode, size_t size)
|
||||||
|
{
|
||||||
|
if(fp->bufmode != _IONBF) {
|
||||||
|
fflush(fp);
|
||||||
|
if(fp->bufowned)
|
||||||
|
free(fp->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
fp->buf = NULL;
|
||||||
|
fp->bufowned = false;
|
||||||
|
fp->bufmode = _IONBF;
|
||||||
|
fp->bufsize = 0;
|
||||||
|
|
||||||
|
if(mode == _IONBF)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if(buf) {
|
||||||
|
fp->buf = buf;
|
||||||
|
fp->bufsize = size;
|
||||||
|
fp->bufmode = mode;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fp->buf = malloc(size);
|
||||||
|
if(!fp->buf)
|
||||||
|
return -1;
|
||||||
|
fp->bufsize = size;
|
||||||
|
fp->bufowned = true;
|
||||||
|
fp->bufmode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue