Browse Source

Add some simple write buffering to LibC's stdio.

Plumb it all the way to the VirtualConsole. Also fix /bin/cat to write()
the whole chunks we get from read() directly to stdout.
Andreas Kling 6 years ago
parent
commit
da3857b0c2
10 changed files with 42 additions and 22 deletions
  1. 6 2
      Kernel/Process.cpp
  2. 1 2
      Kernel/TTY.cpp
  3. 1 1
      Kernel/TTY.h
  4. 5 3
      Kernel/VirtualConsole.cpp
  5. 1 1
      Kernel/VirtualConsole.h
  6. 3 0
      LibC/entry.cpp
  7. 14 8
      LibC/stdio.cpp
  8. 7 2
      LibC/stdio.h
  9. 2 3
      Userland/cat.cpp
  10. 2 0
      Userland/sh.cpp

+ 6 - 2
Kernel/Process.cpp

@@ -29,15 +29,19 @@
 #define VALIDATE_USER_READ(b, s) \
     do { \
         LinearAddress laddr((dword)(b)); \
-        if (!validate_user_read(laddr) || !validate_user_read(laddr.offset((s) - 1))) \
+        if (!validate_user_read(laddr) || !validate_user_read(laddr.offset((s) - 1))) { \
+            dbgprintf("Bad read address passed to syscall: %p +%u\n", laddr.get(), (s)); \
             return -EFAULT; \
+        } \
     } while(0)
 
 #define VALIDATE_USER_WRITE(b, s) \
     do { \
         LinearAddress laddr((dword)(b)); \
-        if (!validate_user_write(laddr) || !validate_user_write(laddr.offset((s) - 1))) \
+        if (!validate_user_write(laddr) || !validate_user_write(laddr.offset((s) - 1))) { \
+            dbgprintf("Bad write address passed to syscall: %p +%u\n", laddr.get(), (s)); \
             return -EFAULT; \
+        } \
     } while(0)
 
 static const DWORD defaultStackSize = 16384;

+ 1 - 2
Kernel/TTY.cpp

@@ -26,8 +26,7 @@ ssize_t TTY::read(byte* buffer, size_t size)
 
 ssize_t TTY::write(const byte* buffer, size_t size)
 {
-    for (size_t i = 0; i < size; ++i)
-        onTTYWrite(buffer[i]);
+    onTTYWrite(buffer, size);
     return 0;
 }
 

+ 1 - 1
Kernel/TTY.h

@@ -21,7 +21,7 @@ protected:
     TTY(unsigned major, unsigned minor);
     void emit(byte);
 
-    virtual void onTTYWrite(byte) = 0;
+    virtual void onTTYWrite(const byte*, size_t) = 0;
 
     void interrupt();
 

+ 5 - 3
Kernel/VirtualConsole.cpp

@@ -320,7 +320,6 @@ void VirtualConsole::put_character_at(unsigned row, unsigned column, byte ch)
 
 void VirtualConsole::on_char(byte ch, bool shouldEmit)
 {
-    InterruptDisabler disabler;
     if (shouldEmit)
         emit(ch);
 
@@ -397,15 +396,18 @@ void VirtualConsole::onKeyPress(Keyboard::Key key)
 
 void VirtualConsole::onConsoleReceive(byte ch)
 {
+    InterruptDisabler disabler;
     auto old_attribute = m_current_attribute;
     m_current_attribute = 0x03;
     on_char(ch, false);
     m_current_attribute = old_attribute;
 }
 
-void VirtualConsole::onTTYWrite(byte ch)
+void VirtualConsole::onTTYWrite(const byte* data, size_t size)
 {
-    on_char(ch, false);
+    InterruptDisabler disabler;
+    for (size_t i = 0; i < size; ++i)
+        on_char(data[i], false);
 }
 
 String VirtualConsole::ttyName() const

+ 1 - 1
Kernel/VirtualConsole.h

@@ -23,7 +23,7 @@ private:
     virtual void onConsoleReceive(byte) override;
 
     // ^TTY
-    virtual void onTTYWrite(byte) override;
+    virtual void onTTYWrite(const byte*, size_t) override;
     virtual String ttyName() const override;
 
     void set_active(bool);

+ 3 - 0
LibC/entry.cpp

@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <string.h>
 #include <Kernel/Syscall.h>
 #include <AK/StringImpl.h>
 
@@ -20,6 +21,8 @@ extern "C" int _start()
 
     errno = 0;
 
+    memset(__default_streams, 0, sizeof(__default_streams));
+
     __default_streams[0].fd = 0;
     stdin = &__default_streams[0];
 

+ 14 - 8
LibC/stdio.cpp

@@ -28,7 +28,11 @@ int fflush(FILE* stream)
     // FIXME: Implement buffered streams, duh.
     if (!stream)
         return -EBADF;
-    return 0;
+    if (!stream->write_buffer_index)
+        return 0;
+    int rc = write(stream->fd, stream->write_buffer, stream->write_buffer_index);
+    stream->write_buffer_index = 0;
+    return rc;
 }
 
 char* fgets(char* buffer, int size, FILE* stream)
@@ -71,7 +75,10 @@ int getchar()
 int fputc(int ch, FILE* stream)
 {
     assert(stream);
-    write(stream->fd, &ch, 1);
+    assert(stream->write_buffer_index < __STDIO_FILE_BUFFER_SIZE);
+    stream->write_buffer[stream->write_buffer_index++] = ch;
+    if (ch == '\n' || stream->write_buffer_index >= __STDIO_FILE_BUFFER_SIZE)
+        fflush(stream);
     if (stream->eof)
         return EOF;
     return (byte)ch;
@@ -99,7 +106,7 @@ int fputs(const char* s, FILE* stream)
 
 int puts(const char* s)
 {
-    fputs(s, stdout);
+    return fputs(s, stdout);
 }
 
 void clearerr(FILE* stream)
@@ -128,6 +135,7 @@ size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream)
 size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream)
 {
     assert(stream);
+    fflush(stream);
     ssize_t nwritten = write(stream->fd, ptr, nmemb * size);
     if (nwritten < 0)
         return 0;
@@ -162,7 +170,7 @@ static void sys_putch(char*&, char ch)
 static FILE* __current_stream = nullptr;
 static void stream_putch(char*&, char ch)
 {
-    write(__current_stream->fd, &ch, 1);
+    fputc(ch, __current_stream);
 }
 
 int fprintf(FILE* fp, const char* fmt, ...)
@@ -211,9 +219,8 @@ FILE* fopen(const char* pathname, const char* mode)
     if (fd < 0)
         return nullptr;
     auto* fp = (FILE*)malloc(sizeof(FILE));
+    memset(fp, 0, sizeof(FILE));
     fp->fd = fd;
-    fp->eof = false;
-    fp->error = 0;
     return fp;
 }
 
@@ -223,9 +230,8 @@ FILE* fdopen(int fd, const char* mode)
     if (fd < 0)
         return nullptr;
     auto* fp = (FILE*)malloc(sizeof(FILE));
+    memset(fp, 0, sizeof(FILE));
     fp->fd = fd;
-    fp->eof = false;
-    fp->error = 0;
     return fp;
 }
 

+ 7 - 2
LibC/stdio.h

@@ -4,8 +4,7 @@
 #include <sys/types.h>
 
 __BEGIN_DECLS
-
-#ifndef EOF
+ #ifndef EOF
 #define EOF (-1)
 #endif
 
@@ -13,10 +12,16 @@ __BEGIN_DECLS
 #define SEEK_CUR 1
 #define SEEK_END 2
 
+#define __STDIO_FILE_BUFFER_SIZE 128
+
 struct __STDIO_FILE {
     int fd;
     int eof;
     int error;
+    char read_buffer[__STDIO_FILE_BUFFER_SIZE];
+    size_t read_buffer_index;
+    char write_buffer[__STDIO_FILE_BUFFER_SIZE];
+    size_t write_buffer_index;
 };
 
 typedef struct __STDIO_FILE FILE;

+ 2 - 3
Userland/cat.cpp

@@ -17,7 +17,7 @@ int main(int argc, char** argv)
         return 1;
     }
     for (;;) {
-        char buf[1024];
+        char buf[4096];
         ssize_t nread = read(fd, buf, sizeof(buf));
         if (nread == 0)
             break;
@@ -25,8 +25,7 @@ int main(int argc, char** argv)
             printf("read() error: %s\n", strerror(errno));
             return 2;
         }
-        for (ssize_t i = 0; i < nread; ++i)
-            putchar(buf[i]);
+        write(1, buf, nread);
     }
     return 0;
 }

+ 2 - 0
Userland/sh.cpp

@@ -25,6 +25,7 @@ static void prompt()
         printf("# ");
     else
         printf("\033[31;1m%s\033[0m@\033[37;1m%s\033[0m:\033[32;1m%s\033[0m$> ", g->username.characters(), g->hostname, g->cwd.characters());
+    fflush(stdout);
 }
 
 static int sh_pwd(int, const char**)
@@ -347,6 +348,7 @@ int main(int, char**)
         }
         for (ssize_t i = 0; i < nread; ++i) {
             putchar(keybuf[i]);
+            fflush(stdout);
             if (keybuf[i] != '\n') {
                 linebuf[linedx++] = keybuf[i];
                 linebuf[linedx] = '\0';