From 162d919194d5ec458eb4772751df3c3309adc4a2 Mon Sep 17 00:00:00 2001 From: "Magomed Kostoev (mkostoevr)" Date: Tue, 2 Mar 2021 18:57:57 +0000 Subject: [PATCH] kolibri-libc: Reimplement fgets, fputc, fputs, fread and fwrite Now it follows the POSIX specification better. git-svn-id: svn://kolibrios.org@8624 a494cfbc-eb01-0410-851d-a64ba20cac60 --- contrib/kolibri-libc/source/stdio/fgetc.c | 33 ++++++++++++++++++++-- contrib/kolibri-libc/source/stdio/fputc.c | 32 +++++++++++++++++++-- contrib/kolibri-libc/source/stdio/fputs.c | 9 +++--- contrib/kolibri-libc/source/stdio/fread.c | 18 +++++++----- contrib/kolibri-libc/source/stdio/fwrite.c | 18 ++++++------ 5 files changed, 85 insertions(+), 25 deletions(-) diff --git a/contrib/kolibri-libc/source/stdio/fgetc.c b/contrib/kolibri-libc/source/stdio/fgetc.c index 089da0807d..c54fd1e704 100644 --- a/contrib/kolibri-libc/source/stdio/fgetc.c +++ b/contrib/kolibri-libc/source/stdio/fgetc.c @@ -1,11 +1,38 @@ #include +#include +#include int fgetc(FILE* stream) { - int c, rc; - rc = fread(&c, sizeof(char), 1, stream); - if(rc<1){ + unsigned bytes_read; + char c; + + unsigned status = _ksys_file_read_file(stream->name, stream->position, 1, &c, &bytes_read); + + if (status != _KOS_FS_ERR_SUCCESS) { + switch (status) { + case _KOS_FS_ERR_EOF: + stream->eof = 1; + break; + case _KOS_FS_ERR_1: + case _KOS_FS_ERR_2: + case _KOS_FS_ERR_3: + case _KOS_FS_ERR_4: + case _KOS_FS_ERR_5: + case _KOS_FS_ERR_7: + case _KOS_FS_ERR_8: + case _KOS_FS_ERR_9: + case _KOS_FS_ERR_10: + case _KOS_FS_ERR_11: + default: + // Just some IO error, who knows what exactly happened + errno = EIO; + stream->error = errno; + break; + } return EOF; } + + stream->position++; return c; } diff --git a/contrib/kolibri-libc/source/stdio/fputc.c b/contrib/kolibri-libc/source/stdio/fputc.c index 5362e56579..da443ea57a 100644 --- a/contrib/kolibri-libc/source/stdio/fputc.c +++ b/contrib/kolibri-libc/source/stdio/fputc.c @@ -1,9 +1,35 @@ #include +#include +#include -int fputc(int sym, FILE *stream) +int fputc(int c, FILE *stream) { - if(!fwrite(&sym, sizeof(char), 1, stream)){ + unsigned bytes_written; + + unsigned status = _ksys_file_write_file(stream->name, stream->position, 1, &c, &bytes_written); + + if (status != _KOS_FS_ERR_SUCCESS) { + switch (status) { + case _KOS_FS_ERR_1: + case _KOS_FS_ERR_2: + case _KOS_FS_ERR_3: + case _KOS_FS_ERR_4: + case _KOS_FS_ERR_5: + case _KOS_FS_ERR_EOF: + case _KOS_FS_ERR_7: + case _KOS_FS_ERR_8: + case _KOS_FS_ERR_9: + case _KOS_FS_ERR_10: + case _KOS_FS_ERR_11: + default: + // Just some IO error, who knows what exactly happened + errno = EIO; + stream->error = errno; + break; + } return EOF; } - return sym; + + stream->position++; + return c; } \ No newline at end of file diff --git a/contrib/kolibri-libc/source/stdio/fputs.c b/contrib/kolibri-libc/source/stdio/fputs.c index 5ae7f14e00..21c60df760 100644 --- a/contrib/kolibri-libc/source/stdio/fputs.c +++ b/contrib/kolibri-libc/source/stdio/fputs.c @@ -2,9 +2,10 @@ #include int fputs(const char *str, FILE *stream){ - int s_code; - for(int i=0; iname, stream->position, bytes_count, ptr, &bytes_read); - stream->position += bytes_read; - ksys_bdfe_t info; - // TODO: Handle _ksys_file_get_info error somehow - if (!_ksys_file_get_info(stream->name, &info)) { - if (stream->position >= info.size) { - stream->eof = 1; + + for (size_t i = 0; i < bytes_count; i++) { + char c = fgetc(stream); + + if (c == EOF) { + break; } + + ptr[i] = c; + + bytes_read++; } + return bytes_read / size; } diff --git a/contrib/kolibri-libc/source/stdio/fwrite.c b/contrib/kolibri-libc/source/stdio/fwrite.c index db44b0fdc4..77ca5239bc 100644 --- a/contrib/kolibri-libc/source/stdio/fwrite.c +++ b/contrib/kolibri-libc/source/stdio/fwrite.c @@ -1,16 +1,18 @@ #include -size_t fwrite(const void * restrict ptr,size_t size, size_t nmemb,FILE * restrict stream) { +size_t fwrite(const void *restrict ptr, size_t size, size_t nmemb, FILE *restrict stream) { unsigned bytes_written = 0; unsigned bytes_count = size * nmemb; - _ksys_file_write_file(stream->name, stream->position, bytes_count, ptr, &bytes_written); - stream->position += bytes_written; - ksys_bdfe_t info; - // TODO: Handle _ksys_file_get_info error somehow - if (!_ksys_file_get_info(stream->name, &info)) { - if (stream->position >= info.size) { - stream->eof = 1; + + for (size_t i = 0; i < bytes_count; i++) { + char c = ptr[i]; + + if (fputc(c, stream) != c) { + break; } + + bytes_written++; } + return bytes_written / size; }