Procházet zdrojové kódy

LibC: Various stdio correctness fixes.

Andreas Kling před 6 roky
rodič
revize
100cb2a237
1 změnil soubory, kde provedl 22 přidání a 11 odebrání
  1. 22 11
      LibC/stdio.cpp

+ 22 - 11
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);
 }