summaryrefslogtreecommitdiff
path: root/LibC/stdio.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-04-27 16:19:11 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-04-27 16:19:11 +0200
commit100cb2a23720936369bf12bbc9d2ea59fa88f4fe (patch)
tree5a2cae1470b875a44b7d6ee438766a069b72cac8 /LibC/stdio.cpp
parent679ac386eb8e48628a08071e1a95cd2f1f1ca5af (diff)
downloadserenity-100cb2a23720936369bf12bbc9d2ea59fa88f4fe.zip
LibC: Various stdio correctness fixes.
Diffstat (limited to 'LibC/stdio.cpp')
-rw-r--r--LibC/stdio.cpp33
1 files changed, 22 insertions, 11 deletions
diff --git a/LibC/stdio.cpp b/LibC/stdio.cpp
index 8b28d8e2ad..c5850cc2f9 100644
--- a/LibC/stdio.cpp
+++ b/LibC/stdio.cpp
@@ -95,16 +95,19 @@ int feof(FILE* stream)
int fflush(FILE* stream)
{
- // FIXME: Implement buffered streams, duh.
- if (!stream)
- return -EBADF;
+ // FIXME: fflush(NULL) should flush all open output streams.
+ ASSERT(stream);
if (!stream->buffer_index)
return 0;
int rc = write(stream->fd, stream->buffer, stream->buffer_index);
stream->buffer_index = 0;
- if (rc < 0)
+ stream->error = 0;
+ stream->eof = 0;
+ if (rc < 0) {
stream->error = errno;
- return rc;
+ return EOF;
+ }
+ return 0;
}
char* fgets(char* buffer, int size, FILE* stream)
@@ -155,6 +158,8 @@ int getchar()
int ungetc(int c, FILE* stream)
{
ASSERT(stream);
+ if (stream->have_ungotten)
+ return EOF;
stream->have_ungotten = true;
stream->ungotten = c;
stream->eof = false;
@@ -170,7 +175,7 @@ int fputc(int ch, FILE* stream)
fflush(stream);
else if (stream->mode == _IONBF || (stream->mode == _IOLBF && ch == '\n'))
fflush(stream);
- if (stream->eof)
+ if (stream->eof || stream->error)
return EOF;
return (byte)ch;
}
@@ -192,14 +197,14 @@ int fputs(const char* s, FILE* stream)
if (rc == EOF)
return EOF;
}
- return 0;
+ return 1;
}
int puts(const char* s)
{
int rc = fputs(s, stdout);
- if (rc < 0)
- return rc;
+ if (rc == EOF)
+ return EOF;
return fputc('\n', stdout);
}
@@ -250,28 +255,34 @@ size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream)
{
assert(stream);
int rc = fflush(stream);
- if (rc < 0)
+ if (rc == EOF)
return 0;
ssize_t nwritten = write(stream->fd, ptr, nmemb * size);
if (nwritten < 0) {
stream->error = errno;
return 0;
}
- return nwritten;
+ return nwritten / size;
}
int fseek(FILE* stream, long offset, int whence)
{
assert(stream);
+ fflush(stream);
off_t off = lseek(stream->fd, offset, whence);
if (off < 0)
return off;
+ stream->eof = false;
+ stream->error = 0;
+ stream->have_ungotten = false;
+ stream->ungotten = 0;
return 0;
}
long ftell(FILE* stream)
{
assert(stream);
+ fflush(stream);
return lseek(stream->fd, 0, SEEK_CUR);
}