Setting O_NONBLOCK via fcntl is not sufficient for TTYs in
non-canonical mode. A subsequent tcsetattr call would override this,
as the default VMIN and VTIME settings cause the driver to block.
Explicitly set VMIN and VTIME to 0 to ensure a true non-blocking read.
Also, apply these TTY settings to STDIN_FILENO instead of STDOUT_FILENO.
This is semantically more correct as we are configuring input behavior.
Fixes#26166.
Doing that will currently result in an unkillable process. Simply
disallowing this shouldn't cause any real incompatibilities since Linux
doesn't allow attaching to threads in the same thread group either.
The mmap() call here served no purpose - anon_create() is only meant to
create and return a file descriptor. The actual mapping is done later
by AnonymousBufferImpl::create().
This leaked an mmap of `size` bytes for every AnonymousBuffer created,
which includes backing stores, shareable bitmaps, and more.
(cherry picked from commit 07630f3b0c4e08771a75edcc68ab3fdbc8948b2f)
CMake learned which gcc flag to translate `set(CMAKE_CXX_STANDARD 26)`
to in CMake 3.30.0:
https://gitlab.kitware.com/cmake/cmake/-/merge_requests/9434
Using earlier versions leads to
...requires the language dialect "CXX26" . But the
current compiler "GCC" does not support this, or CMake does not know
the flags to enable it.
errors after #26524.
Without this, when I updated CMake and then ran this script, it failed
right after the bootstrap phase with:
loading initial cache file /Users/thakis/src/serenity/Toolchain/
Build/cmake/Bootstrap.cmk/InitialCacheFlags.cmake
CMake Error: The source "/Users/thakis/src/serenity/Toolchain/
Tarballs/cmake-3.30.0/CMakeLists.txt" does not match the source
"/Users/thakis/src/serenity/Toolchain/Tarballs/cmake-3.25.1/
CMakeLists.txt" used to generate cache. Re-run cmake with a
different source directory.
---------------------------------------------
Error when bootstrapping CMake:
Problem while running initial CMake
---------------------------------------------
Forcing a clean build dir resolves this.
Not being able to find a reason for a page fault doesn't necessarily
mean that it's a bug. As page faults can happen concurrently (even
without SMP), one thread can already be done handling to a page, while
another thread took a longer time to start handling a page fault to
the same page. In this situation, the second thread won't find a reason
for the page fault, therefore it would previously crash.
To clarify this problem, here a problematic example situation:
On a SMP system, two threads A and B are causing a page fault to the
exact same page at exactly the same time. Thread A enters the page fault
handler, but immediately gets an interrupt after we enable interrupts
again. This interrupt takes quite a long time to handle. Thread B on the
hand immediately enters the page fault handler immediately and handles
the page fault successfully before thread A even entered the page fault
handler. Now thread A finished handling its interrupt and enters the
page fault handler as well, but it can't find a reason for it, so it
crashes.
We can't prevent this situation with spinlocks, since when page faults
happen is not under our control. Therefore the page fault handler needs
to be able to handle situations where the reason for the page fault is
already gone.
Since not being able to find a reason for the page fault can still also
mean that we have a bug in the page fault handler, add some extra
assertions checking if an address translation with the associated page
table entry would still fail. If it would, then this is a kernel bug
and we should panic.
Similar to the last commit, two page faults to the same page can happen
concurrently, so we need to be able to handle this properly.
Previously, we only held the VMObject's lock in
AnonymousVMObject::handle_cow_fault. But as explained in the previous
commit this isn't enough. We need to keep holding the lock until the
page is remapped.
Additionally, this commit makes handle_cow_fault() take a global lock
to make concurrent page faults to the same page from different processes
work correctly.
This global lock is unfortunately necessary since fork() clones all
VMObjects, so taking its lock won't prevent another process from
handling a page fault to the same physical pages. See the FIXME comment
for details.
There might be a better way to fix this, but this fix should still be
better than potentially panicking when concurrent COW faults occur.
This essentially reverts 5ada38f9c3.
Previously, two threads could end up trying to allocate a committed
page at once, possibly resulting in a panic because we tried to
allocate more pages than committed.
Another problem was that a thread could incorrectly think that the page
fault was already handled. This can happen if the thread handling the
page fault already set the physical page slot to the newly allocated
page, but didn't remap the page yet. We check if a page fault was
already processed based on the physical page slot contents.
This issue is not causing problems currently, since thinking a page
fault was already handled and incorrectly returning will still work
eventually when the other thread is done remapping the page.
However, a future commit will add extra assertions checking that page
faults were already handled appropriately if we couldn't find a reason
for the fault. These assertions would trip on this.
Prevent these issues by taking the lock for a longer amount of time.
There might be a better solution to this, but that would likely require
more complex code changes.
Also modify the code in handle_fault() a bit to avoid using should_cow()
for zero faults. The checks in should_cow() can refer to a different
physical page if the page fault was handled immediately after the check.
Instead of having to maintain two different page fault handler
implementations, let's unify the two by using the more generic RISC-V
implementation.
The RISC-V implementation doesn't depend on the processor providing the
reason why a page fault occured.
We don't need to know whether it's a NotPresent or ProtectionViolation
fault to handle it correctly, as we already have enough metadata.
This causes us to print a more useful error message than "Unexpected
page fault".
Additionally, this change will be necessary in a future commit, which
expects us to handle all reasons for page faults exhaustively.
This matches the x86-64 and AArch64 behavior.
This required moving the is_instruction_fetch() check before the
is_read() check, since is_read() is now also true for instruction fetch
page faults.
... and always use it for inode write faults.
In the RISC-V page fault implementation, we previously only used this
function if `should_dirty_on_write()` returned true. If it didn't, we'd
use `handle_inode_fault()`. But this shouldn't be necessary, since
`handle_dirty_on_write_fault()` already handles cases where the page
isn't mapped yet.
This should now also cause a page to be immediately marked as dirty
if the first access to it was a write. Previously, this should have
caused two page faults: one for loading the inode page and one for
making it dirty.
This code in the x86-64 and AArch64 page fault handler should be
unreachable, since Region::map_individual_page_impl() always maps all
non-null physical pages, therefore we should never get a PageNotPresent
fault if the page slot is set to a non-null value.
Lazy committed pages are implemented by mapping them read-only, so a
write access to them will result in a ProtectionViolation fault, which
will call very similar code in Region::handle_zero_fault().
Similarly in the RISC-V version, we already handle lazy committed page
faults by calling Region::handle_zero_fault() a couple lines earlier
if the page fault was generated by a write access and the region is
writable.
Previously, the Run application would always execute commands using
/bin/Shell, ignoring the user's configuration.
This change retrieves the current user's preferred shell via
Core::Account. If the preferred shell cannot be determined or does
not exist on the filesystem, it falls back to /bin/Shell.
A warning message is displayed if the configured shell is missing
to inform the user of the fallback.
This adds a global search term stored in BrowserWindow that is shared
across all tabs. When opening Find in Page (Ctrl+F), the widget now
uses the following priority logic:
1. If there's text selected on the page, use that
2. If the search box is empty, use the global search term
3. Otherwise, keep the existing text
To imitatates Chromium's logic, the global search term is updated
whenever the user types, navigates matches, or when a selection
populates the search box.
This adds a FindInPageWidget to the Browser application, allowing users
to search for text within the current tab.
Features:
- Search textbox with real-time search as you type
- Previous/Next buttons with up/down arrow icons
- Match Case checkbox to toggle case sensitivity
- Result label showing "X of Y matches" or "Phrase not found"
- Close button to hide the widget
Keyboard shortcuts:
- Ctrl+F: Open find-in-page widget
- Enter: Jump to next match
- Shift+Enter: Jump to previous match
- Escape: Close the widget
The widget integrates with LibWebView's existing find_in_page,
find_in_page_next_match, and find_in_page_previous_match APIs.
This patch clears the stopped state in Process::die() while holding the
scheduler lock, ensuring that threads can be correctly resumed to clean
up their kernel stacks before exiting.
Previously, the advice window used a connector at a fixed absolute
position at the middle of the bubble. This resulted in visual
disconnection as there was no logic to check if the advice bubble
was currently positioned above or below CatDog.
Changes:
- Implemented dynamic calculation for the connector's starting point.
- Added logic to detect the relative vertical position of the advice
bubble compared to the CatDog character.
- Updated the drawing routine to flip or adjust the connector
direction based on that relative position.
This patch ensures the connector remains visually in sync with
CatDog's position, providing a cohesive UI regardless of where the
advice window is rendered.
After identifying that `advice_window` gets clipped on either axis, and
sometimes rendered completely out of screen itself. This issue was due
to lack of screen-bounds checks before positioning window.
Changes:
- Added notion of minimum_required_margin so that window doesnt stick to
edges.
- Added bounds check for advice_window_x and clamp within bounds.
- Added bounds check for advice_window_y and move window below catdog if
no space is present above.
This brings advice-window within rendered part of screen.