1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:17:36 +00:00

LibC: Various stdio correctness fixes.

This commit is contained in:
Andreas Kling 2019-04-27 16:19:11 +02:00
parent 679ac386eb
commit 100cb2a237

View file

@ -95,16 +95,19 @@ int feof(FILE* stream)
int fflush(FILE* stream) int fflush(FILE* stream)
{ {
// FIXME: Implement buffered streams, duh. // FIXME: fflush(NULL) should flush all open output streams.
if (!stream) ASSERT(stream);
return -EBADF;
if (!stream->buffer_index) if (!stream->buffer_index)
return 0; return 0;
int rc = write(stream->fd, stream->buffer, stream->buffer_index); int rc = write(stream->fd, stream->buffer, stream->buffer_index);
stream->buffer_index = 0; stream->buffer_index = 0;
if (rc < 0) stream->error = 0;
stream->eof = 0;
if (rc < 0) {
stream->error = errno; stream->error = errno;
return rc; return EOF;
}
return 0;
} }
char* fgets(char* buffer, int size, FILE* stream) char* fgets(char* buffer, int size, FILE* stream)
@ -155,6 +158,8 @@ int getchar()
int ungetc(int c, FILE* stream) int ungetc(int c, FILE* stream)
{ {
ASSERT(stream); ASSERT(stream);
if (stream->have_ungotten)
return EOF;
stream->have_ungotten = true; stream->have_ungotten = true;
stream->ungotten = c; stream->ungotten = c;
stream->eof = false; stream->eof = false;
@ -170,7 +175,7 @@ int fputc(int ch, FILE* stream)
fflush(stream); fflush(stream);
else if (stream->mode == _IONBF || (stream->mode == _IOLBF && ch == '\n')) else if (stream->mode == _IONBF || (stream->mode == _IOLBF && ch == '\n'))
fflush(stream); fflush(stream);
if (stream->eof) if (stream->eof || stream->error)
return EOF; return EOF;
return (byte)ch; return (byte)ch;
} }
@ -192,14 +197,14 @@ int fputs(const char* s, FILE* stream)
if (rc == EOF) if (rc == EOF)
return EOF; return EOF;
} }
return 0; return 1;
} }
int puts(const char* s) int puts(const char* s)
{ {
int rc = fputs(s, stdout); int rc = fputs(s, stdout);
if (rc < 0) if (rc == EOF)
return rc; return EOF;
return fputc('\n', stdout); return fputc('\n', stdout);
} }
@ -250,28 +255,34 @@ size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream)
{ {
assert(stream); assert(stream);
int rc = fflush(stream); int rc = fflush(stream);
if (rc < 0) if (rc == EOF)
return 0; return 0;
ssize_t nwritten = write(stream->fd, ptr, nmemb * size); ssize_t nwritten = write(stream->fd, ptr, nmemb * size);
if (nwritten < 0) { if (nwritten < 0) {
stream->error = errno; stream->error = errno;
return 0; return 0;
} }
return nwritten; return nwritten / size;
} }
int fseek(FILE* stream, long offset, int whence) int fseek(FILE* stream, long offset, int whence)
{ {
assert(stream); assert(stream);
fflush(stream);
off_t off = lseek(stream->fd, offset, whence); off_t off = lseek(stream->fd, offset, whence);
if (off < 0) if (off < 0)
return off; return off;
stream->eof = false;
stream->error = 0;
stream->have_ungotten = false;
stream->ungotten = 0;
return 0; return 0;
} }
long ftell(FILE* stream) long ftell(FILE* stream)
{ {
assert(stream); assert(stream);
fflush(stream);
return lseek(stream->fd, 0, SEEK_CUR); return lseek(stream->fd, 0, SEEK_CUR);
} }