diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-03-27 01:40:55 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-03-27 01:40:55 +0100 |
commit | d1e55fb4d95c790155f427bac980a1c24a1360f7 (patch) | |
tree | 3e37057c7d5c7136c5207b4f71e9f65725183252 /LibC/stdio.cpp | |
parent | 0c2face7b0756ac5d8523551f20a95716d77b9c5 (diff) | |
download | serenity-d1e55fb4d95c790155f427bac980a1c24a1360f7.zip |
LibC: Add ungetc() and automatically flush streams on fclose().
Diffstat (limited to 'LibC/stdio.cpp')
-rw-r--r-- | LibC/stdio.cpp | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/LibC/stdio.cpp b/LibC/stdio.cpp index 9a976b4bb1..49de4da1c1 100644 --- a/LibC/stdio.cpp +++ b/LibC/stdio.cpp @@ -141,9 +141,12 @@ int getchar() return getc(stdin); } -int ungetc(int, FILE*) +int ungetc(int c, FILE* stream) { - ASSERT_NOT_REACHED(); + ASSERT(stream); + stream->have_ungotten = true; + stream->ungotten = c; + return c; } int fputc(int ch, FILE* stream) @@ -203,6 +206,18 @@ int ferror(FILE* stream) size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream) { assert(stream); + if (!size) + return 0; + + if (stream->have_ungotten) { + // FIXME: Support ungotten character even if size != 1. + ASSERT(size == 1); + ((char*)ptr)[0] = stream->ungotten; + stream->have_ungotten = false; + --nmemb; + ptr = &((char*)ptr)[1]; + } + ssize_t nread = read(stream->fd, ptr, nmemb * size); if (nread < 0) return 0; @@ -388,6 +403,7 @@ FILE* fdopen(int fd, const char* mode) int fclose(FILE* stream) { + fflush(stream); int rc = close(stream->fd); free(stream); return rc; |