1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-19 20:35:06 +00:00

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.
This commit is contained in:
Andreas Kling 2018-11-08 01:23:23 +01:00
parent e287f8ef3a
commit da3857b0c2
10 changed files with 42 additions and 22 deletions

View file

@ -29,15 +29,19 @@
#define VALIDATE_USER_READ(b, s) \ #define VALIDATE_USER_READ(b, s) \
do { \ do { \
LinearAddress laddr((dword)(b)); \ 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; \ return -EFAULT; \
} \
} while(0) } while(0)
#define VALIDATE_USER_WRITE(b, s) \ #define VALIDATE_USER_WRITE(b, s) \
do { \ do { \
LinearAddress laddr((dword)(b)); \ 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; \ return -EFAULT; \
} \
} while(0) } while(0)
static const DWORD defaultStackSize = 16384; static const DWORD defaultStackSize = 16384;

View file

@ -26,8 +26,7 @@ ssize_t TTY::read(byte* buffer, size_t size)
ssize_t TTY::write(const 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, size);
onTTYWrite(buffer[i]);
return 0; return 0;
} }

View file

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

View file

@ -320,7 +320,6 @@ void VirtualConsole::put_character_at(unsigned row, unsigned column, byte ch)
void VirtualConsole::on_char(byte ch, bool shouldEmit) void VirtualConsole::on_char(byte ch, bool shouldEmit)
{ {
InterruptDisabler disabler;
if (shouldEmit) if (shouldEmit)
emit(ch); emit(ch);
@ -397,15 +396,18 @@ void VirtualConsole::onKeyPress(Keyboard::Key key)
void VirtualConsole::onConsoleReceive(byte ch) void VirtualConsole::onConsoleReceive(byte ch)
{ {
InterruptDisabler disabler;
auto old_attribute = m_current_attribute; auto old_attribute = m_current_attribute;
m_current_attribute = 0x03; m_current_attribute = 0x03;
on_char(ch, false); on_char(ch, false);
m_current_attribute = old_attribute; 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 String VirtualConsole::ttyName() const

View file

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

View file

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

View file

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

View file

@ -4,8 +4,7 @@
#include <sys/types.h> #include <sys/types.h>
__BEGIN_DECLS __BEGIN_DECLS
#ifndef EOF
#ifndef EOF
#define EOF (-1) #define EOF (-1)
#endif #endif
@ -13,10 +12,16 @@ __BEGIN_DECLS
#define SEEK_CUR 1 #define SEEK_CUR 1
#define SEEK_END 2 #define SEEK_END 2
#define __STDIO_FILE_BUFFER_SIZE 128
struct __STDIO_FILE { struct __STDIO_FILE {
int fd; int fd;
int eof; int eof;
int error; 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; typedef struct __STDIO_FILE FILE;

View file

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

View file

@ -25,6 +25,7 @@ static void prompt()
printf("# "); printf("# ");
else 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()); 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**) static int sh_pwd(int, const char**)
@ -347,6 +348,7 @@ int main(int, char**)
} }
for (ssize_t i = 0; i < nread; ++i) { for (ssize_t i = 0; i < nread; ++i) {
putchar(keybuf[i]); putchar(keybuf[i]);
fflush(stdout);
if (keybuf[i] != '\n') { if (keybuf[i] != '\n') {
linebuf[linedx++] = keybuf[i]; linebuf[linedx++] = keybuf[i];
linebuf[linedx] = '\0'; linebuf[linedx] = '\0';