Instead of doing so in the constructor, let's do immediately after the
constructor, so we can safely pass a reference of a Device, so the
SysFSDeviceComponent constructor can use that object to identify whether
it's a block device or a character device.
This allows to us to not hold a device in SysFSDeviceComponent with a
RefPtr.
Also, we also call the before_removing method in both SlavePTY::unref
and File::unref, so because Device has that method being overrided, it
can ensure the device is removed always cleanly.
These methods are no longer needed because SystemServer is able to
populate the DevFS on its own.
Device absolute_path no longer assume a path to the /dev location,
because it really should not assume any path to a Device node.
Because StorageManagement still needs to know the storage name, we
declare a virtual method only for StorageDevices to override, but this
technique should really be removed later on.
This expands the reach of error propagation greatly throughout the
kernel. Sadly, it also exposes the fact that we're allocating (and
doing other fallible things) in constructors all over the place.
This patch doesn't attempt to address that of course. That's work for
our future selves.
The default template argument is only used in one place, and it
looks like it was probably just an oversight. The rest of the Kernel
code all uses u8 as the type. So lets make that the default and remove
the unused template argument, as there doesn't seem to be a reason to
allow the size to be customizable.
This is the idiomatic way to declare type aliases in modern C++.
Flagged by Sonar Cloud as a "Code Smell", but I happen to agree
with this particular one. :^)
This has several benefits:
1) We no longer just blindly derefence a null pointer in various places
2) We will get nicer runtime error messages if the current process does
turn out to be null in the call location
3) GCC no longer complains about possible nullptr dereferences when
compiling without KUBSAN
This simplifies the DevPtsFS implementation somewhat, as it no longer
requires SlavePTY to register itself with it, since it can now simply
use the list of SlavePTY instances.
The maximum number of virtual consoles is determined at compile time,
so we can pre-allocate that many slots, dodging some heap allocations.
Furthermore, virtual consoles are never destroyed, so it's fine to
simply store a raw pointer to the currently active one.
VirtualConsole::m_lock was only used in a single place: on_tty_write()
That function is already protected by a global lock, so this second
lock served no purpose whatsoever.
Now that all KResult and KResultOr are used consistently throughout the
kernel, it's no longer necessary to return negative error codes.
However, we were still doing that in some places, so let's fix all those
(bugs) by removing the minuses. :^)
In preparation for modifying the Kernel IOCTL API to return KResult
instead of int, we need to fix this ioctl to an argument to receive
it's return value, instead of using the actual function return value.
It's easy to forget the responsibility of validating and safely copying
kernel parameters in code that is far away from syscalls. ioctl's are
one such example, and bugs there are just as dangerous as at the root
syscall level.
To avoid this case, utilize the AK::Userspace<T> template in the ioctl
kernel interface so that implementors have no choice but to properly
validate and copy ioctl pointer arguments.
These small changes fix the remaining warnings that come up during
kernel compilation with Clang. These specific fixes were for benign
things: unused lambda captures and braces around scalar initializers.
This commit converts naked `new`s to `AK::try_make` and `AK::try_create`
wherever possible. If the called constructor is private, this can not be
done, so we instead now use the standard-defined and compiler-agnostic
`new (nothrow)`.
The `File::can_write` mechanism lets us check that writes won't block,
meaning some bytes can be immediately written to the underlying device.
This means calling `File::write` in a situation where no data could be
written is a logic error, which we `VERIFY()` in `Process::do_write()`.
TTY, in particular, processes the write in 256-byte buffered chunks.
Previously, we would assert that none of these sub-writes returned zero.
This was a logic error, as this rejected some successful writes. For
example, if there was exactly enough free space in `SlavePty`'s internal
buffer for the previous sub-write to complete fully. This made it
impossible to perform writes larger than `SlavePty`'s internal buffer.
Note that it's not an issue if `on_tty_write` returns zero, as partial
writes are handled correctly by the `buffer.read_buffered` helper. We
won't spin in a loop trying to write to a full buffer.
Fixes#8090
Previously the VirtualConsole::on_tty_write() method would return an
incorrect value when an error had occurred. This prompted me to
update the TTY subsystem to use KResultOr<size_t> everywhere.
If we do not flush the dirty lines, characters typed in canonical mode
only appear after the virtual console has been switched away from, or
the application has been killed. Instead, we now immediately perform the
flush.
If lines are removed from the tail of the scrollback buffer, the
previous line indices will refer to different lines; therefore we need
to offset them.
This commit implements the left/right scrolling used in the `ICH`/`DCH`
escape sequences for `VirtualConsole`. This brings us one step closer to
VT420/xterm compatibility.
We can now finally remove the last escape sequence related `ifdef`s.
Previously, this was done by telling the client to put a space at each
character in the range. This was inefficient, because a large number of
function calls took place and incorrect, as the ANSI standard dictates
that character attributes should be cleared as well.
The newly added `clear_in_line` function solves this issue. It performs
just one bounds check when it's called and can be implemented as a
pretty tight loop.
This commit cleans up some of the `#ifdef`-ed code smell in
`Terminal`, by extending the scroll APIs to take a range of lines as a
parameter. This makes it possible to use the same code for `IL`/`DL` as
for scrolling.
Note that the current scrolling implementation is very naive, and does
many insertions/deletions in the middle of arrays, whereas swaps should
be enough. This optimization will come in a later commit.
The `linefeed` override was removed from `VirtualConsole`. Previously,
it exhibited incorrect behavior by moving to column 0. Now that we use
the method defined in `Terminal`, code which relied on this behavior
stopped working. We go instead go through the TTY layer which handles
the various output flags. Passing the input character-by-character
seems a bit excessive, so a fix for it will come in another PR.
Previously, we would echo characters back just as they were passed to
us, even in canonical mode. This caused newlines to not work correctly
in some programs.
Fixes#7802
Previously, we converted colors to their RGB values immediately when
they were set. This meant that their semantic meaning was lost, we could
not tell a precise RGB value apart from a named/indexed color.
The new way of storing colors will allow us to retain this information,
so we can change a color scheme on the fly, and previously emitted text
will also be affected.
The changes in commit 20743e8 removed the s_max_virtual_consoles
constant and hardcoded the number of consoles to 4. But in
PS2KeyboardDevice the keyboard shortcuts for switching to consoles were
hardcoded to 6.
I reintroduced the constant and added it in both places.
The Alternate Screen Buffer is used by full-screen terminal applications
(like `vim` and `nano`). Its data is stored separately from the normal
buffer, therefore after applications using it exit, everything looks
like it was before, the bottom of their interfaces isn't visible. An
interesting feature is that it does not support scrollback, so it
consumes less memory by not having to allocate lines for history.
Because of the need to save and restore state between the switches, some
correctness issues relating to it were also fixed in this commit.
This commit introduces support for 3 new escape sequences:
1. Stop blinking cursor mode
2. `DECTCEM` mode (enable/disable cursor)
3. `DECSCUSR` (set cursor style)
`TerminalWidget` now supports the following cursor types: block,
underline and vertical bar. Each of these can blink or be steady.
`VirtualConsole` ignores these (just as we were doing before).
I introduced a regression in #7184 where `TTY` would report 1 byte read
in canonical mode even if we had no more characters left. This was
caused by counting the '\0' that denotes EOF into the number of
characters that were read.
The fix was simple: exclude the EOF character from the number of bytes.
This still wouldn't be correct by itself, as the EOF and EOL control
characters could change between when the data was written to the TTY and
when it is read. We fix this by signaling out-of-band whether something
is a special character. End-of-file markers have a value of zero and
have their special bits set. Any other bytes with a special flag are
treated as line endings. This is possible, as POSIX doesn't allow
special characters to be 0.
Fixes#7419
If we tried to change the resolution before of this patch, we triggered
a kernel crash due to mmaping the framebuffer device again.
Therefore, on mmaping of the framebuffer device, we create an entire new
set of VMObjects and Regions for the new settings.
Then, when we change the resolution, the framebuffersconsole needs to be
updated with the new resolution and also to be refreshed with the new
settings. To ensure we handle both shrinking of the resolution and
growth of it, we only copy the right amount of available data from the
cells Region.
Problem:
- `static` variables consume memory and sometimes are less
optimizable.
- `static const` variables can be `constexpr`, usually.
- `static` function-local variables require an initialization check
every time the function is run.
Solution:
- If a global `static` variable is only used in a single function then
move it into the function and make it non-`static` and `constexpr`.
- Make all global `static` variables `constexpr` instead of `const`.
- Change function-local `static const[expr]` variables to be just
`constexpr`.
Fixes a bug where TTY::write will attempt to write into the underlying
device but will not acknowledge the result of that write, instead
assuming that the write fully completed.
Before this commit, we would jump to the first column after receiving
the '\n' line feed character. This is not the correct behavior, as it
should only move the cursor now. Translating the typed Return key into
the correct CR LF ("\r\n") is the TTY's job, which was fixed in #7184.
Fixes#6820Fixes#6960
This commit adds support for the various ECHO* lflags and fixes some
POSIX conformance issues around newline handling. Also included are
error messages when setting not implemented settings.
As we removed the support of VBE modesetting that was done by GRUB early
on boot, we need to determine if we can modeset the resolution with our
drivers, and if not, we should enable text mode and ensure that
SystemServer knows about it too.
Also, SystemServer should first check if there's a framebuffer device
node, which is an indication that text mode was not even if it was
requested. Then, if it doesn't find it, it should check what boot_mode
argument the user specified (in case it's self-test). This way if we
try to use bochs-display device (which is not VGA compatible) and
request a text mode, it will not honor the request and will continue
with graphical mode.
Also try to print critical messages with mininum memory allocations
possible.
In LibVT, We make the implementation flexible for kernel-specific
methods that are implemented in ConsoleImpl class.
This non-POSIX header is used in Linux/BSD systems for storing the
default termios settings. This lets us setup new TTYs' `m_termios.c_cc`
in a nicer way than using a magic string.
By constraining two implementations, the compiler will select the best
fitting one. All this will require is duplicating the implementation and
simplifying for the `void` case.
This constraining also informs both the caller and compiler by passing
the callback parameter types as part of the constraint
(e.g.: `IterationFunction<int>`).
Some `for_each` functions in LibELF only take functions which return
`void`. This is a minimal correctness check, as it removes one way for a
function to incompletely do something.
There seems to be a possible idiom where inside a lambda, a `return;` is
the same as `continue;` in a for-loop.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
The end goal of this commit is to allow to boot on bare metal with no
PS/2 device connected to the system. It turned out that the original
code relied on the existence of the PS/2 keyboard, so VirtualConsole
called it even though ACPI indicated the there's no i8042 controller on
my real machine because I didn't plug any PS/2 device.
The code is much more flexible, so adding HID support for other type of
hardware (e.g. USB HID) could be much simpler.
Briefly describing the change, we have a new singleton called
HIDManagement, which is responsible to initialize the i8042 controller
if exists, and to enumerate its devices. I also abstracted a bit
things, so now every Human interface device is represented with the
HIDDevice class. Then, there are 2 types of it - the MouseDevice and
KeyboardDevice classes; both are responsible to handle the interface in
the DevFS.
PS2KeyboardDevice, PS2MouseDevice and VMWareMouseDevice classes are
responsible for handling the hardware-specific interface they are
assigned to. Therefore, they are inheriting from the IRQHandler class.
Added a dummy TIOCSTI ioctl placeholder. This is a dangerous ioctl that
can be used to inject input into a tty. Added for compatibility. Always
fails with EIO.
Alot of code is shared between i386/i686/x86 and x86_64
and a lot probably will be used for compatability modes.
So we start by moving the headers into one Directory.
We will probalby be able to move some cpp files aswell.
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED)
Since all of these checks are done in release builds as well,
let's rename them to VERIFY to prevent confusion, as everyone is
used to assertions being compiled out in release.
We can introduce a new ASSERT macro that is specifically for debug
checks, but I'm doing this wholesale conversion first since we've
accumulated thousands of these already, and it's not immediately
obvious which ones are suitable for ASSERT.
There's no real system here, I just added it to various functions
that I don't believe we ever want to call after initialization
has finished.
With these changes, we're able to unmap 60 KiB of kernel text
after init. :^)
Besides removing the monolithic DevFSDeviceInode::determine_name()
method, being able to determine a device's name inside the /dev
hierarchy outside of DevFS has its uses.