diff options
author | Andreas Kling <awesomekling@gmail.com> | 2018-11-08 01:23:23 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2018-11-08 01:23:47 +0100 |
commit | da3857b0c23a4e99edc2481c93c7f3bebda510cc (patch) | |
tree | e32c162d311a06f3678b28a967344b04c9f77ee0 | |
parent | e287f8ef3adc88112e1c2336adc4a27365058db8 (diff) | |
download | serenity-da3857b0c23a4e99edc2481c93c7f3bebda510cc.zip |
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.
-rw-r--r-- | Kernel/Process.cpp | 8 | ||||
-rw-r--r-- | Kernel/TTY.cpp | 3 | ||||
-rw-r--r-- | Kernel/TTY.h | 2 | ||||
-rw-r--r-- | Kernel/VirtualConsole.cpp | 8 | ||||
-rw-r--r-- | Kernel/VirtualConsole.h | 2 | ||||
-rw-r--r-- | LibC/entry.cpp | 3 | ||||
-rw-r--r-- | LibC/stdio.cpp | 22 | ||||
-rw-r--r-- | LibC/stdio.h | 9 | ||||
-rw-r--r-- | Userland/cat.cpp | 5 | ||||
-rw-r--r-- | Userland/sh.cpp | 2 |
10 files changed, 42 insertions, 22 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index c7ecaa01be..19aec8c7bf 100644 --- a/Kernel/Process.cpp +++ b/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; diff --git a/Kernel/TTY.cpp b/Kernel/TTY.cpp index 382ac2a6f8..2ad8c50a72 100644 --- a/Kernel/TTY.cpp +++ b/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; } diff --git a/Kernel/TTY.h b/Kernel/TTY.h index 856e8c79d8..a54a7a1f42 100644 --- a/Kernel/TTY.h +++ b/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(); diff --git a/Kernel/VirtualConsole.cpp b/Kernel/VirtualConsole.cpp index 6512758c92..d77fb06888 100644 --- a/Kernel/VirtualConsole.cpp +++ b/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 diff --git a/Kernel/VirtualConsole.h b/Kernel/VirtualConsole.h index 205e567f3e..6ef8ec7927 100644 --- a/Kernel/VirtualConsole.h +++ b/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); diff --git a/LibC/entry.cpp b/LibC/entry.cpp index d8dc22d565..0fd3783d73 100644 --- a/LibC/entry.cpp +++ b/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]; diff --git a/LibC/stdio.cpp b/LibC/stdio.cpp index c75f99d621..5c1409591f 100644 --- a/LibC/stdio.cpp +++ b/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; } diff --git a/LibC/stdio.h b/LibC/stdio.h index a662321953..452dddee5d 100644 --- a/LibC/stdio.h +++ b/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; diff --git a/Userland/cat.cpp b/Userland/cat.cpp index ab003a2a7d..04453054f8 100644 --- a/Userland/cat.cpp +++ b/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; } diff --git a/Userland/sh.cpp b/Userland/sh.cpp index e3b40174f6..9a4706dc52 100644 --- a/Userland/sh.cpp +++ b/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'; |