From ac7a60225e9c2024a167d6f3f440780cf7af304a Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 29 Nov 2018 03:45:23 +0100 Subject: Add TIOCGWINSZ ioctl so userland can determine terminal geometry. (Don't) use this to implement short-form output in ls. I'm too tired to make a nice column formatting algorithm. I just wanted something concise when I type "ls". --- Kernel/TTY.cpp | 14 ++++++++++++++ Kernel/TTY.h | 6 ++++++ Kernel/VirtualConsole.cpp | 39 ++++++++++++++++++++------------------- Kernel/VirtualConsole.h | 2 -- Kernel/run | 6 +++--- Kernel/sync.sh | 2 ++ 6 files changed, 45 insertions(+), 24 deletions(-) (limited to 'Kernel') diff --git a/Kernel/TTY.cpp b/Kernel/TTY.cpp index ebd5146d42..8325f56c4f 100644 --- a/Kernel/TTY.cpp +++ b/Kernel/TTY.cpp @@ -109,6 +109,7 @@ int TTY::ioctl(Process& process, unsigned request, unsigned arg) { pid_t pgid; Unix::termios* tp; + Unix::winsize* ws; if (process.tty() != this) return -ENOTTY; @@ -136,7 +137,20 @@ int TTY::ioctl(Process& process, unsigned request, unsigned arg) return -EFAULT; set_termios(*tp); return 0; + case TIOCGWINSZ: + ws = reinterpret_cast(arg); + if (!process.validate_write(ws, sizeof(Unix::winsize))) + return -EFAULT; + ws->ws_row = m_rows; + ws->ws_col = m_columns; + return 0; } ASSERT_NOT_REACHED(); return -EINVAL; } + +void TTY::set_size(unsigned short columns, unsigned short rows) +{ + m_rows = rows; + m_columns = columns; +} diff --git a/Kernel/TTY.h b/Kernel/TTY.h index e1d5f36874..5d58c44c3f 100644 --- a/Kernel/TTY.h +++ b/Kernel/TTY.h @@ -39,6 +39,9 @@ public: virtual String ttyName() const = 0; + unsigned short rows() const { return m_rows; } + unsigned short columns() const { return m_columns; } + void set_pgid(pid_t pgid) { m_pgid = pgid; } pid_t pgid() const { return m_pgid; } @@ -50,6 +53,7 @@ public: protected: virtual void onTTYWrite(const byte*, size_t) = 0; + void set_size(unsigned short columns, unsigned short rows); TTY(unsigned major, unsigned minor); void emit(byte); @@ -63,5 +67,7 @@ private: DoubleBuffer m_buffer; pid_t m_pgid { 0 }; Unix::termios m_termios; + unsigned short m_rows { 0 }; + unsigned short m_columns { 0 }; }; diff --git a/Kernel/VirtualConsole.cpp b/Kernel/VirtualConsole.cpp index f9f3df9435..f0708f74cd 100644 --- a/Kernel/VirtualConsole.cpp +++ b/Kernel/VirtualConsole.cpp @@ -17,13 +17,13 @@ void VirtualConsole::get_vga_cursor(byte& row, byte& column) value = IO::in8(0x3d5) << 8; IO::out8(0x3d4, 0x0f); value |= IO::in8(0x3d5); - row = value / 80; - column = value % 80; + row = value / columns(); + column = value % columns(); } void VirtualConsole::flush_vga_cursor() { - word value = m_current_vga_start_address + (m_cursor_row * 80 + m_cursor_column); + word value = m_current_vga_start_address + (m_cursor_row * columns() + m_cursor_column); IO::out8(0x3d4, 0x0e); IO::out8(0x3d5, MSB(value)); IO::out8(0x3d4, 0x0f); @@ -41,14 +41,15 @@ VirtualConsole::VirtualConsole(unsigned index, InitialContents initial_contents) : TTY(4, index) , m_index(index) { + set_size(80, 25); s_consoles[index] = this; - m_buffer = (byte*)kmalloc_eternal(80 * 25 * 2); + m_buffer = (byte*)kmalloc_eternal(rows() * columns() * 2); if (initial_contents == AdoptCurrentVGABuffer) { - memcpy(m_buffer, s_vga_buffer, 80 * 25 * 2); + memcpy(m_buffer, s_vga_buffer, rows() * columns() * 2); get_vga_cursor(m_cursor_row, m_cursor_column); } else { word* line_mem = reinterpret_cast(m_buffer); - for (word i = 0; i < 80 * 25; ++i) + for (word i = 0; i < rows() * columns(); ++i) line_mem[i] = 0x0720; } } @@ -60,7 +61,7 @@ VirtualConsole::~VirtualConsole() void VirtualConsole::clear() { word* linemem = m_active ? (word*)s_vga_buffer : (word*)m_buffer; - for (word i = 0; i < 80 * 25; ++i) + for (word i = 0; i < rows() * columns(); ++i) linemem[i] = 0x0720; if (m_active) set_vga_start_row(0); @@ -91,11 +92,11 @@ void VirtualConsole::set_active(bool b) m_active = b; if (!m_active) { - memcpy(m_buffer, m_current_vga_window, 80 * 25 * 2); + memcpy(m_buffer, m_current_vga_window, rows() * columns() * 2); return; } - memcpy(s_vga_buffer, m_buffer, 80 * 25 * 2); + memcpy(s_vga_buffer, m_buffer, rows() * columns() * 2); set_vga_start_row(0); flush_vga_cursor(); @@ -325,16 +326,16 @@ void VirtualConsole::execute_escape_sequence(byte final) void VirtualConsole::clear_vga_row(word row) { word* linemem = (word*)&m_current_vga_window[row * 160]; - for (word i = 0; i < 80; ++i) + for (word i = 0; i < columns(); ++i) linemem[i] = 0x0720; } void VirtualConsole::scroll_up() { - if (m_cursor_row == (m_rows - 1)) { + if (m_cursor_row == (rows() - 1)) { if (m_active) { if (m_vga_start_row >= 160) { - memcpy(s_vga_buffer, m_current_vga_window + 160, 80 * 24 * 2); + memcpy(s_vga_buffer, m_current_vga_window + 160, (rows() - 1) * columns() * 2); set_vga_start_row(0); clear_vga_row(24); } else { @@ -344,7 +345,7 @@ void VirtualConsole::scroll_up() } else { memcpy(m_buffer, m_buffer + 160, 160 * 24); word* linemem = (word*)&m_buffer[24 * 160]; - for (word i = 0; i < 80; ++i) + for (word i = 0; i < columns(); ++i) linemem[i] = 0x0720; } } else { @@ -355,8 +356,8 @@ void VirtualConsole::scroll_up() void VirtualConsole::set_cursor(unsigned row, unsigned column) { - ASSERT(row < m_rows); - ASSERT(column < m_columns); + ASSERT(row < rows()); + ASSERT(column < columns()); m_cursor_row = row; m_cursor_column = column; if (m_active) @@ -365,8 +366,8 @@ void VirtualConsole::set_cursor(unsigned row, unsigned column) void VirtualConsole::put_character_at(unsigned row, unsigned column, byte ch) { - ASSERT(row < m_rows); - ASSERT(column < m_columns); + ASSERT(row < rows()); + ASSERT(column < columns()); word cur = (row * 160) + (column * 2); if (m_active) { word cur = (row * 160) + (column * 2); @@ -435,7 +436,7 @@ void VirtualConsole::on_char(byte ch) put_character_at(m_cursor_row, m_cursor_column, ch); ++m_cursor_column; - if (m_cursor_column >= m_columns) + if (m_cursor_column >= columns()) scroll_up(); set_cursor(m_cursor_row, m_cursor_column); } @@ -480,7 +481,7 @@ String VirtualConsole::ttyName() const void VirtualConsole::set_vga_start_row(word row) { m_vga_start_row = row; - m_current_vga_start_address = row * 80; + m_current_vga_start_address = row * columns(); m_current_vga_window = s_vga_buffer + row * 160; IO::out8(0x3d4, 0x0c); IO::out8(0x3d5, MSB(m_current_vga_start_address)); diff --git a/Kernel/VirtualConsole.h b/Kernel/VirtualConsole.h index 4aae3bad0e..39f1d7dfce 100644 --- a/Kernel/VirtualConsole.h +++ b/Kernel/VirtualConsole.h @@ -49,8 +49,6 @@ private: void clear(); - const byte m_rows { 25 }; - const byte m_columns { 80 }; byte m_cursor_row { 0 }; byte m_cursor_column { 0 }; byte m_saved_cursor_row { 0 }; diff --git a/Kernel/run b/Kernel/run index 5fe20b9986..d679046148 100755 --- a/Kernel/run +++ b/Kernel/run @@ -1,8 +1,8 @@ #!/bin/sh -if [ "$1" = "b" ]; then - bochs -q -f .bochsrc -else +if [ "$1" = "q" ]; then qemu-system-i386 -s -m 32 -drive format=raw,file=.floppy-image,if=floppy -drive format=raw,file=_fs_contents #$@ +else + bochs -q -f .bochsrc fi diff --git a/Kernel/sync.sh b/Kernel/sync.sh index de4586d43e..130ceba83c 100755 --- a/Kernel/sync.sh +++ b/Kernel/sync.sh @@ -32,5 +32,7 @@ cp -v ../Userland/strsignal mnt/bin/strsignal cp -v ../Userland/mkdir mnt/bin/mkdir sh sync-local.sh cp -v kernel.map mnt/ +ln -s dir_a mnt/dir_cur +ln -s nowhere mnt/bad_link umount mnt sync -- cgit v1.2.3