summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2018-11-08 01:23:23 +0100
committerAndreas Kling <awesomekling@gmail.com>2018-11-08 01:23:47 +0100
commitda3857b0c23a4e99edc2481c93c7f3bebda510cc (patch)
treee32c162d311a06f3678b28a967344b04c9f77ee0
parente287f8ef3adc88112e1c2336adc4a27365058db8 (diff)
downloadserenity-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.cpp8
-rw-r--r--Kernel/TTY.cpp3
-rw-r--r--Kernel/TTY.h2
-rw-r--r--Kernel/VirtualConsole.cpp8
-rw-r--r--Kernel/VirtualConsole.h2
-rw-r--r--LibC/entry.cpp3
-rw-r--r--LibC/stdio.cpp22
-rw-r--r--LibC/stdio.h9
-rw-r--r--Userland/cat.cpp5
-rw-r--r--Userland/sh.cpp2
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';