From 366cc2549a305a886f1de2f93fad78e93f2e8751 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Mon, 12 Mar 2012 00:38:48 +0100 Subject: [PATCH] Added the stdio_ext(3) API. The API is available in without __ prefix if _SORTIX_SOURCE. --- libmaxsi/decl/FILE.h | 3 ++ libmaxsi/file.c | 69 ++++++++++++++++++++++++++++++++++-- libmaxsi/include/stdio.h | 13 ++++++- libmaxsi/include/stdio_ext.h | 57 +++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 libmaxsi/include/stdio_ext.h diff --git a/libmaxsi/decl/FILE.h b/libmaxsi/decl/FILE.h index 1dd4d458..2e16dad4 100644 --- a/libmaxsi/decl/FILE.h +++ b/libmaxsi/decl/FILE.h @@ -3,6 +3,9 @@ #define BUFSIZ 8192UL #define _FILE_REGISTERED (1<<0) #define _FILE_NO_BUFFER (1<<1) +#define _FILE_LAST_WRITE (1<<2) +#define _FILE_LAST_READ (1<<3) +#define _FILE_AUTO_LOCK (1<<4) typedef struct _FILE { /* This is non-standard, but useful. If you allocate your own FILE and diff --git a/libmaxsi/file.c b/libmaxsi/file.c index 1ae41826..acb51fa8 100644 --- a/libmaxsi/file.c +++ b/libmaxsi/file.c @@ -53,12 +53,14 @@ void funregister(FILE* fp) size_t fread(void* ptr, size_t size, size_t nmemb, FILE* fp) { if ( !fp->read_func ) { errno = EBADF; return 0; } - return fp->read_func(ptr, size, nmemb, fp->user); + fp->flags &= ~_FILE_LAST_WRITE; fp->flags |= _FILE_LAST_READ; + return fp->read_func(ptr, size, nmemb, fp->user); } size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* fp) { if ( !fp->write_func ) { errno = EBADF; return 0; } + fp->flags &= ~_FILE_LAST_READ; fp->flags |= _FILE_LAST_WRITE; char* str = (char*) ptr; size_t total = size * nmemb; size_t sofar = 0; @@ -168,6 +170,61 @@ int fileno(FILE* fp) return result; } +size_t fbufsize(FILE* fp) +{ + return fp->buffersize; +} + +int freading(FILE* fp) +{ + if ( fp->read_func ) { return 1; } + if ( fp->flags & _FILE_LAST_READ ) { return 1; } + return 0; +} + +int fwriting(FILE* fp) +{ + if ( fp->write_func ) { return 1; } + if ( fp->flags & _FILE_LAST_WRITE ) { return 1; } + return 0; +} + +int freadable(FILE* fp) +{ + return fp->read_func != NULL; +} + +int fwritable(FILE* fp) +{ + return fp->write_func != NULL; +} + +int flbf(FILE* fp) +{ + return !(fp->flags & _FILE_NO_BUFFER); +} + +void fpurge(FILE* fp) +{ + fp->bufferused = 0; +} + +size_t fpending(FILE* fp) +{ + return fp->bufferused; +} + +int fsetlocking(FILE* fp, int type) +{ + switch ( type ) + { + case FSETLOCKING_INTERNAL: fp->flags |= _FILE_AUTO_LOCK; + case FSETLOCKING_BYCALLER: fp->flags &= ~_FILE_AUTO_LOCK; + } + return (fp->flags & _FILE_AUTO_LOCK) ? FSETLOCKING_INTERNAL + : FSETLOCKING_BYCALLER; +} + static void ffreefile(FILE* fp) { free(fp->buffer); @@ -181,7 +238,7 @@ FILE* fnewfile(void) fp->buffersize = BUFSIZ; fp->buffer = (char*) malloc(fp->buffersize); if ( !fp->buffer ) { free(fp); return NULL; } - fp->flags = 0; + fp->flags = _FILE_AUTO_LOCK; fp->free_func = ffreefile; fregister(fp); return fp; @@ -194,6 +251,14 @@ int fcloseall(void) return (result) ? EOF : 0; } +void flushlbf(void) +{ + for ( FILE* fp = firstfile; fp; fp = fp->next ) + { + fflush(fp); + } +} + int fgetc(FILE* fp) { unsigned char c; diff --git a/libmaxsi/include/stdio.h b/libmaxsi/include/stdio.h index 8af2f2cd..1617c00a 100644 --- a/libmaxsi/include/stdio.h +++ b/libmaxsi/include/stdio.h @@ -1,6 +1,6 @@ /****************************************************************************** - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011, 2012. This file is part of LibMaxsi. @@ -148,6 +148,17 @@ extern char* tempnam(const char* dir, const char* pfx); #endif #if defined(_SORTIX_SOURCE) +#include +#define fbufsize __fbufsize +#define freading __freading +#define fwriting __fwriting +#define freadable __freadable +#define fwritable __fwritable +#define flbf __flbf +#define fpurge __fpurge +#define fpending __fpending +#define flushlbf _flushlbf +#define fsetlocking __fsetlocking void fregister(FILE* fp); void funregister(FILE* fp); FILE* fnewfile(void); diff --git a/libmaxsi/include/stdio_ext.h b/libmaxsi/include/stdio_ext.h new file mode 100644 index 00000000..2a6d8414 --- /dev/null +++ b/libmaxsi/include/stdio_ext.h @@ -0,0 +1,57 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. + + This file is part of LibMaxsi. + + LibMaxsi is free software: you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + LibMaxsi is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + more details. + + You should have received a copy of the GNU Lesser General Public License + along with LibMaxsi. If not, see . + + stdio_ext.h + Extensions to stdio.h introduced by Solaris and glibc. + +******************************************************************************/ + +#ifndef _STDIO_EXT_H +#define _STDIO_EXT_H 1 + +#include +#include + +enum +{ + FSETLOCKING_QUERY = 0, + FSETLOCKING_INTERNAL, + FSETLOCKING_BYCALLER, +}; + +#define FSETLOCKING_QUERY FSETLOCKING_QUERY +#define FSETLOCKING_INTERNAL FSETLOCKING_INTERNAL +#define FSETLOCKING_BYCALLER FSETLOCKING_BYCALLER + +__BEGIN_DECLS + +extern size_t __fbufsize(FILE* fp); +extern int __freading(FILE* fp); +extern int __fwriting(FILE* fp); +extern int __freadable(FILE* fp); +extern int __fwritable(FILE* fp); +extern int __flbf(FILE* fp); +extern void __fpurge(FILE* fp); +extern size_t __fpending(FILE* fp); +extern void _flushlbf(void); +extern int __fsetlocking(FILE* fp, int type); + +__END_DECLS + +#endif