Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
205 commits
Select commit Hold shift + click to select a range
aaad8e9
feat(libkernel_sys): implement pwrite through the shared POSIX provider
yabanana Oct 21, 2026
096195d
Merge main and address review for PR 9019
yabanana Oct 23, 2026
b28c59f
fix(libkernel): retain shared-memory descriptor flags on Windows
yabanana Oct 23, 2026
f07cd28
fix(libkernel): bound sequential shared-memory writes on Windows
yabanana Oct 23, 2026
b843e6c
fix(libkernel_sys): retain the current process-query declaration
yabanana Oct 23, 2026
f302e49
docs(libkernel_sys): remove resolved pwrite error-precedence debt
yabanana Oct 23, 2026
c5447f8
fix(libkernel): bound scalar writes to anonymous shared memory
harry-z-kang Oct 23, 2026
2dd3d69
Merge main and preserve pipe and fixed-size descriptor state
yabanana Oct 24, 2026
970fc48
Merge main and preserve named shared-memory dispatch and public signa…
yabanana Oct 25, 2026
6d2225e
test(libkernel): check named-object write bounds before concurrency
yabanana Oct 25, 2026
1d653c9
fix(libkernel): honor per-call nonblocking socket transfers
lgqdaxia Oct 25, 2026
d3d5a4d
fix(libkernel): restart socket timeouts after progress
lgqdaxia Oct 25, 2026
981fffb
fix(ssl): bound Unix retained socket transfers
Queuse Oct 25, 2026
9b50a9c
test(libkernel): reject retained socket deadline extension
lgqdaxia Oct 25, 2026
904fcc6
fix(libkernel): honor live Unix socket modes in retained transfers
lgqdaxia Oct 25, 2026
6adaa5a
test(libkernel): cover retained Unix socket mode changes
lgqdaxia Oct 25, 2026
c1082f4
fix(libkernel): reconcile pwrite metadata with current main
yabanana Oct 26, 2026
82fafdc
fix(libkernel): retain pwrite guards and split named-memory checks
yabanana Oct 26, 2026
a23af5d
chore(libkernel): compose released-thread handle prerequisite
Felipebmaitan Oct 27, 2026
0fbaef4
feat(libkernel): cancel blocked POSIX reads safely
Felipebmaitan Oct 27, 2026
23dba78
fix(libkernel): preserve read validation and partial receive progress
Felipebmaitan Oct 27, 2026
857c3e8
fix(libkernel): preserve descriptor ownership during cancellable reads
Felipebmaitan Oct 27, 2026
c63fba6
fix(libkernel): preserve stream locking and bounded descriptor state
Felipebmaitan Oct 27, 2026
686ae27
chore(libkernel): integrate current main for read cancellation
Felipebmaitan Oct 27, 2026
a39219f
chore(libkernel): compose current read lifetime prerequisite
Felipebmaitan Oct 27, 2026
3f3f324
fix(libkernel): retain zero-length receives and append handles
Felipebmaitan Oct 27, 2026
7177d3a
chore(libkernel): compose stdio descriptor lifetime prerequisite
Felipebmaitan Oct 27, 2026
5550769
chore(libkernel): record incremental read review base
Felipebmaitan Oct 27, 2026
2eee76f
chore(libkernel): compose read lifetime prerequisites
Felipebmaitan Oct 27, 2026
6a95e13
fix(libkernel): release read ownership before asynchronous signal han…
Felipebmaitan Oct 27, 2026
82c9029
chore(libkernel): integrate current main before signal review
Felipebmaitan Oct 27, 2026
cad3634
test(libkernel): bound signal delivery coverage and check I/O startup…
Felipebmaitan Oct 27, 2026
35d1e6f
chore(libkernel): compose current read cancellation prerequisites
Felipebmaitan Oct 27, 2026
faf62ef
chore(libkernel): record updated read cancellation review base
Felipebmaitan Oct 27, 2026
f30678f
chore(libkernel): compose updated read cancellation prerequisites
Felipebmaitan Oct 27, 2026
6de6c5b
fix(libkernel): preserve I/O delivery across user contexts
Felipebmaitan Oct 27, 2026
0e45e49
chore(libkernel): integrate current read cancellation prerequisites
Felipebmaitan Oct 27, 2026
5cfba81
fix(libkernel): identify suspended I/O contexts without stack registries
Felipebmaitan Oct 27, 2026
cf6dbf6
chore(libkernel): compose current publication prerequisites
Felipebmaitan Oct 27, 2026
4e5cd17
test(libkernel): verify restarting handlers that change errno
Felipebmaitan Oct 27, 2026
e93539c
chore(libkernel): integrate current publication prerequisites
Felipebmaitan Oct 27, 2026
24c755f
chore(libkernel): integrate current main for close review
Felipebmaitan Oct 27, 2026
0403250
fix(libkernel): wake admitted POSIX reads before closing
Felipebmaitan Oct 27, 2026
fdd4ba3
fix(libkernel): handle mixed close and pre-call interruption errors
Felipebmaitan Oct 27, 2026
bcf5df1
docs(libkernel): clarify remaining close limitations concisely
Felipebmaitan Oct 27, 2026
f1bfb9b
chore(libkernel): compose blocking-write prerequisites
Felipebmaitan Oct 27, 2026
f1b34b6
chore(libkernel): compose the native nonblocking transport prerequisite
Felipebmaitan Oct 27, 2026
12f084e
chore(libkernel): prepare the read prerequisite review base
Felipebmaitan Oct 27, 2026
eebaac5
fix(libkernel): retain I/O signal state through native thread teardown
Felipebmaitan Oct 27, 2026
4527224
fix(libc): preserve descriptor coordination across patched libraries
Felipebmaitan Oct 27, 2026
a30255f
chore(libkernel): integrate reviewed read prerequisites
Felipebmaitan Oct 27, 2026
ee9bca6
fix(libkernel): retain read cancellation across native socket transpo…
Felipebmaitan Oct 27, 2026
c9917f6
docs(libkernel): correct retained socket wait limitations
Felipebmaitan Oct 27, 2026
8c68efe
chore(libkernel): refresh reviewed reads with current main
Felipebmaitan Oct 27, 2026
3c360d5
chore(libkernel): compose transport with current reads
Felipebmaitan Oct 27, 2026
f21940e
feat(libkernel): cancel blocked POSIX writes safely
Felipebmaitan Oct 27, 2026
10dbaaa
fix(libkernel): cancel contended shared-memory writes
Felipebmaitan Oct 27, 2026
beb4837
test(libkernel): tighten blocked-write lifecycle handshakes
Felipebmaitan Oct 27, 2026
3c7e9ec
test(libkernel): cover synchronous-write cancellation boundaries
Felipebmaitan Oct 27, 2026
7480e2f
fix(libkernel): cancel synchronous flushes and restricted pipe writes
Felipebmaitan Oct 27, 2026
e87a337
fix(libkernel): guard synchronous-write metadata waits
Felipebmaitan Oct 27, 2026
dc7772e
fix(libkernel): cancel write preflight metadata queries
Felipebmaitan Oct 27, 2026
21d5a97
chore: integrate current main for posix-io-cancellation-reads
Felipebmaitan Oct 28, 2026
5b2d107
chore(libkernel): integrate current main into write cancellation
Felipebmaitan Oct 28, 2026
560f498
chore(libkernel): retain refreshed read prerequisite in write stack
Felipebmaitan Oct 28, 2026
d0ac607
chore: reconcile kernel contribution with current main
yabanana Oct 28, 2026
06036bf
chore(libkernel): compose read cancellation with current main
Felipebmaitan Oct 29, 2026
3b0d2c6
fix(libkernel): retain renamed kqueue checks in read wrappers
Felipebmaitan Oct 29, 2026
1bbc5d2
Merge branch 'feat/posix-read-cancellation-core' into feat/posix-sock…
Felipebmaitan Oct 29, 2026
5764c77
fix(libkernel): reuse the thread socket transfer waker
Felipebmaitan Oct 29, 2026
3c20c17
test(libkernel): bind the transfer waker reuse endpoint
Felipebmaitan Oct 29, 2026
7b3caa0
test(libkernel): handshake socket transfer waker reuse
Felipebmaitan Oct 29, 2026
9c4889a
chore(libkernel): compose writes above the separate transport layer
Felipebmaitan Oct 29, 2026
7644bae
test(libkernel): preserve synchronous-write progress across interruption
Felipebmaitan Oct 29, 2026
d0d6abc
fix(libkernel): retain written bytes when synchronous flushing is int…
Felipebmaitan Oct 29, 2026
8ef7f85
test(libkernel): cover disconnected Windows pipe writers
Felipebmaitan Oct 29, 2026
7a2c024
fix(libkernel): report broken peers for disconnected pipe writes
Felipebmaitan Oct 29, 2026
79b02b3
fix(libkernel_sys): reconcile shared-memory tests and document offset…
yabanana Oct 29, 2026
056c4b4
feat(libc): export _setjmp and _longjmp
AlexFigas Oct 27, 2026
5f6d8e8
chore(libkernel): refresh cancellation reads against main
Felipebmaitan Oct 29, 2026
cb4335c
test(libkernel): force stream close lock interleavings
Felipebmaitan Oct 29, 2026
654ba49
chore: compose thread prerequisite review base
Felipebmaitan Oct 29, 2026
e5e1732
chore: compose read prerequisite review base
Felipebmaitan Oct 29, 2026
bc9022d
test(libkernel): check POSIX admission while a stream close waits
Felipebmaitan Oct 29, 2026
d7e75a0
feat(kernel): make POSIX accept cancellation-safe
Felipebmaitan Oct 29, 2026
f1d9305
chore(libkernel): record the composed prerequisite comparison base
Felipebmaitan Oct 29, 2026
1fb274f
chore(libkernel): propagate reviewed read close regressions
Felipebmaitan Oct 29, 2026
d828f6c
chore(libkernel): refresh writes with reviewed cancellation prerequis…
Felipebmaitan Oct 29, 2026
31a43bb
chore: refresh accept cancellation prerequisites
Felipebmaitan Oct 29, 2026
096b544
docs(kernel): shorten socket alias cancellation debt
Felipebmaitan Oct 29, 2026
23691a5
chore: compose write cancellation prerequisite
Felipebmaitan Oct 29, 2026
543e97b
Merge remote-tracking branch 'origin/main' into reference/posix-reads…
Felipebmaitan Oct 29, 2026
15a594b
Merge branch 'reference/posix-reads-composed-base' into feat/posix-re…
Felipebmaitan Oct 29, 2026
b00ee2c
chore(libkernel): refresh posix-socket-blocking-transport prerequisites
Felipebmaitan Oct 29, 2026
5c5defe
chore(libkernel): refresh posix-write-cancellation-core prerequisites
Felipebmaitan Oct 29, 2026
55161f9
test(libkernel): await readable data before nonblocking receive races
Felipebmaitan Oct 30, 2026
5dce7fe
chore(libkernel): refresh posix-socket-blocking-transport prerequisites
Felipebmaitan Oct 30, 2026
f3b780c
chore(libkernel): refresh posix-write-cancellation-core prerequisites
Felipebmaitan Oct 30, 2026
daa3a81
fix(libkernel): initialize default blocking send limits
Felipebmaitan Oct 30, 2026
35bee36
chore: refresh accept cancellation prerequisites
Felipebmaitan Oct 30, 2026
70ce098
chore: refresh accept cancellation with current main
Felipebmaitan Oct 30, 2026
75b5ef3
chore: record composed accept prerequisite base
Felipebmaitan Oct 30, 2026
e01288c
chore: record exact accept prerequisite comparison
Felipebmaitan Oct 30, 2026
4ce41ad
Merge upstream main into feat/libc-underscore-setjmp
AlexFigas Oct 30, 2026
ccc7482
Merge commit 'refs/pull/12149/head' of https://github.com/boykopovar/…
Felipebmaitan Oct 31, 2026
078a861
chore: merge current main into read cancellation stack
Felipebmaitan Oct 31, 2026
75147ee
fix(libc): restore I/O contexts through underscore jumps
Felipebmaitan Oct 31, 2026
545eef4
chore(libkernel): compose current read prerequisites into transport
Felipebmaitan Oct 31, 2026
2bf768b
Merge commit 'refs/io-feedback/transport' into HEAD
Felipebmaitan Oct 31, 2026
ed4af92
Merge commit 'refs/io-feedback/writes' into HEAD
Felipebmaitan Oct 31, 2026
592b32a
test(libkernel): bound and diagnose context delivery hangs
Felipebmaitan Oct 31, 2026
90f1c5f
chore: compose current main and read prerequisites
Felipebmaitan Oct 31, 2026
0e88eee
chore: record exact reads prerequisite comparison
Felipebmaitan Oct 31, 2026
30eab60
chore: record exact transport prerequisite comparison
Felipebmaitan Oct 31, 2026
86dfdc9
chore: record exact writes prerequisite comparison
Felipebmaitan Oct 31, 2026
e654da0
chore: record exact accept prerequisite comparison
Felipebmaitan Oct 31, 2026
8fdab41
chore: compose underscore jumps as read prerequisite
Felipebmaitan Oct 31, 2026
03c2195
Merge upstream main into feat/libc-underscore-setjmp
AlexFigas Nov 1, 2026
4888011
chore(libkernel): integrate current main into cancellation reads
Felipebmaitan Nov 1, 2026
a84b9bd
chore(libkernel): compose macOS prerequisite before cancellation reads
Felipebmaitan Nov 1, 2026
8b74140
Merge commit 'refs/io-feedback/pr-12149' into HEAD
Felipebmaitan Nov 1, 2026
8af4225
fix(libkernel): bound I/O retries and shard descriptor ownership
Felipebmaitan Nov 1, 2026
4bd5030
chore(libkernel): retain current main validation in socket transport
Felipebmaitan Nov 1, 2026
0c0f702
chore(libkernel): retain macOS vector guards and descriptor passing i…
Felipebmaitan Nov 1, 2026
20a55f7
chore(libkernel): compose current cancellation prerequisites into accept
Felipebmaitan Nov 1, 2026
ee8a3b9
test(libkernel): fault inject accepted descriptor installation and di…
Felipebmaitan Nov 1, 2026
c8a209b
Merge commit 'refs/io-feedback/nov1-writes' into HEAD
Felipebmaitan Nov 1, 2026
f5d67c6
fix(libkernel): retain cancellation for main descriptor-passing sends
Felipebmaitan Nov 1, 2026
17f4e57
test(libkernel): count Linux native descriptors through procfs
Felipebmaitan Nov 1, 2026
98e9567
chore: compose main into cancellation comparison prerequisites
Felipebmaitan Nov 1, 2026
56ca395
chore: compose macOS and underscore-jump prerequisite heads
Felipebmaitan Nov 1, 2026
00dedbf
chore: record refreshed reads prerequisite comparison
Felipebmaitan Nov 1, 2026
98621b9
chore: record refreshed transport prerequisite comparison
Felipebmaitan Nov 1, 2026
121ac8e
chore: record refreshed writes prerequisite comparison
Felipebmaitan Nov 1, 2026
8c15021
chore: record refreshed accept prerequisite comparison
Felipebmaitan Nov 1, 2026
274fd6f
chore: compose macOS and underscore-jump prerequisite heads
Felipebmaitan Nov 1, 2026
5d01e01
test(libkernel): drain the interrupted native-entry control before re…
Felipebmaitan Nov 1, 2026
c6359ca
Merge commit 'refs/io-feedback/nov1-reads' into HEAD
Felipebmaitan Nov 1, 2026
a8bb330
Merge commit 'refs/io-feedback/nov1-transport' into HEAD
Felipebmaitan Nov 1, 2026
7606c75
Merge commit 'refs/io-feedback/nov1-writes' into HEAD
Felipebmaitan Nov 1, 2026
beda865
Merge commit 'refs/io-feedback/nov1-reads' into HEAD
Felipebmaitan Nov 1, 2026
b988f51
Merge commit 'refs/io-feedback/nov1-transport' into HEAD
Felipebmaitan Nov 1, 2026
ce73e60
Merge commit 'refs/pr/base' into HEAD
Felipebmaitan Nov 1, 2026
c6c5591
Merge commit 'refs/io-feedback/nov1-writes' into HEAD
Felipebmaitan Nov 1, 2026
f0d4972
chore: record current transport comparison ancestor
Felipebmaitan Nov 1, 2026
3175192
chore: record current writes comparison ancestor
Felipebmaitan Nov 1, 2026
327cb8a
chore: record current reads comparison ancestor
Felipebmaitan Nov 1, 2026
af9cd6d
chore: record current main in comparison prerequisites
Felipebmaitan Nov 1, 2026
d682ea7
test(libkernel): wire reservation failure before accepted socket inst…
Felipebmaitan Nov 1, 2026
0376e15
fix(libkernel): retain datagram source-fault error precedence
Felipebmaitan Nov 2, 2026
c2b279e
Merge commit 'refs/io-feedback/wake-transport' into HEAD
Felipebmaitan Nov 2, 2026
93e4d25
Merge commit 'refs/io-feedback/wake-writes' into HEAD
Felipebmaitan Nov 2, 2026
c155f5f
fix(libkernel): integrate main and retain Windows drain coverage
Felipebmaitan Nov 2, 2026
d417845
fix(libkernel): propagate main integration into transport
Felipebmaitan Nov 2, 2026
5968a32
fix(libkernel): propagate main integration into writes
Felipebmaitan Nov 2, 2026
de53948
fix(libkernel): propagate main integration into accept
Felipebmaitan Nov 2, 2026
258548a
test(libkernel): warm transfer waker before accept leak snapshots
Felipebmaitan Nov 2, 2026
5a3085a
chore: record integrated accept comparison ancestry
Felipebmaitan Nov 2, 2026
c962560
chore: record integrated writes comparison ancestry
Felipebmaitan Nov 2, 2026
b0b8c21
chore: record integrated reads comparison ancestry
Felipebmaitan Nov 2, 2026
94b38c1
chore: record integrated transport comparison ancestry
Felipebmaitan Nov 2, 2026
6fd8146
chore: compose current main and declared I/O prerequisites
Felipebmaitan Nov 2, 2026
db09379
test(libkernel): measure accept disposal after connection setup
Felipebmaitan Nov 2, 2026
1e6b694
Merge main 096c45570f into #9019 (79b02b3bdb)
oneandonlydean Nov 2, 2026
a422276
fix(libkernel): compose shared pwrite before write cancellation
Felipebmaitan Nov 2, 2026
36403b5
chore: integrate current main into write cancellation
Felipebmaitan Nov 2, 2026
51a3073
test(libkernel): exercise cancellation through the sys pwrite provider
Felipebmaitan Nov 2, 2026
11f74fd
fix(libkernel): propagate shared pwrite composition to accept
Felipebmaitan Nov 2, 2026
b34cb17
chore: compose write comparison prerequisites
Felipebmaitan Nov 2, 2026
0c1e3f8
chore: record shared pwrite comparison base
Felipebmaitan Nov 2, 2026
b9c6f4d
chore: record shared pwrite comparison ancestry
Felipebmaitan Nov 2, 2026
7deae3f
chore: preserve accept incremental comparison ancestry
Felipebmaitan Nov 2, 2026
acd2259
chore: integrate current main into read cancellation
Felipebmaitan Nov 3, 2026
5288759
chore: propagate current main into blocking transport
Felipebmaitan Nov 3, 2026
48daa05
chore: propagate current main into write cancellation
Felipebmaitan Nov 3, 2026
048e198
chore: propagate current main into accept cancellation
Felipebmaitan Nov 3, 2026
97a5bb6
chore: compose current main and read comparison prerequisites
Felipebmaitan Nov 3, 2026
13a35be
chore: compose current shared pwrite comparison prerequisites
Felipebmaitan Nov 3, 2026
da29e64
chore: retain current read comparison ancestry
Felipebmaitan Nov 3, 2026
0c661a1
chore: retain current write comparison ancestry
Felipebmaitan Nov 3, 2026
3df2c01
chore: retain current transport comparison ancestry
Felipebmaitan Nov 3, 2026
4749c62
chore: retain current accept comparison ancestry
Felipebmaitan Nov 3, 2026
32169af
docs(libkernel): keep composed context debt concise
Felipebmaitan Nov 3, 2026
704935f
docs(libkernel): propagate concise context debt to writes
Felipebmaitan Nov 3, 2026
35e16ad
docs(libkernel): propagate concise context debt to transport
Felipebmaitan Nov 3, 2026
495a1a5
docs(libkernel): propagate concise context debt to accept
Felipebmaitan Nov 3, 2026
b718e81
chore: retain shared pwrite comparison prerequisites
Felipebmaitan Nov 3, 2026
49b52e2
chore: retain refreshed write comparison ancestry
Felipebmaitan Nov 3, 2026
1574087
chore: retain refreshed accept comparison ancestry
Felipebmaitan Nov 3, 2026
085458a
fix(libkernel): retry partial-buffer socket probes within transport w…
Felipebmaitan Nov 3, 2026
7c1fb0d
chore: retain refreshed shared pwrite comparison prerequisites
Felipebmaitan Nov 3, 2026
439c4c1
fix(libkernel): propagate transport probe retries to write cancellation
Felipebmaitan Nov 3, 2026
1624caa
chore: retain write comparison after transport review fixes
Felipebmaitan Nov 3, 2026
853a0d4
fix(libkernel): propagate reviewed transport behavior to accept
Felipebmaitan Nov 3, 2026
a8038f6
docs(libkernel): propagate retained SSL wait debt placement
Felipebmaitan Nov 3, 2026
8957ad0
docs(libSceSsl): locate retained transport debt with its owning library
Felipebmaitan Nov 3, 2026
13de4e7
chore: retain reviewed transport and pwrite comparison prerequisites
Felipebmaitan Nov 3, 2026
022410b
chore: retain write comparison after debt placement fix
Felipebmaitan Nov 3, 2026
858e850
docs(libkernel): propagate reviewed transport debt to accept
Felipebmaitan Nov 3, 2026
4f89794
docs(libSceSsl): keep retained transport debt in its lists
Felipebmaitan Nov 3, 2026
70120f1
test(libkernel): expect unsupported blocking peek contract
Felipebmaitan Nov 3, 2026
7125cb9
chore: retain transport test and pwrite comparison prerequisites
Felipebmaitan Nov 3, 2026
a96d495
test(libkernel): propagate blocking peek expectation to writes
Felipebmaitan Nov 3, 2026
fbd44d3
chore: retain write comparison after peek assertion fix
Felipebmaitan Nov 3, 2026
27a82bc
test(libkernel): propagate blocking peek expectation to accept
Felipebmaitan Nov 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions core/libs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,21 @@ if(BUILD_TESTING)
add_test(NAME nid_elf_layout COMMAND ${Python3_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/nid/tests/test_elf_layout.py $<TARGET_FILE:nid_patcher>)
endif()
add_test_executable(guest_kernel_sys_pwrite_tests tests/GuestKernelSysPwrite.cpp
nid/src/NidCompute.cpp nid/src/Sha1.cpp)
target_include_directories(guest_kernel_sys_pwrite_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/nid/include)
target_link_libraries(guest_kernel_sys_pwrite_tests PRIVATE ${CMAKE_DL_LIBS})
add_custom_target(guest_kernel_sys_pwrite_libraries DEPENDS
${PATCHED_DIR}/libkernel_sys.prx ${PATCHED_DIR}/libkernel.prx ${LIBC_PATCHED})
add_dependencies(guest_kernel_sys_pwrite_tests guest_kernel_sys_pwrite_libraries)
configure_windows_unwind(guest_kernel_sys_pwrite_tests)
if(MINGW)
target_compile_options(guest_kernel_sys_pwrite_tests PRIVATE -fasynchronous-unwind-tables)
target_link_options(guest_kernel_sys_pwrite_tests PRIVATE -static -static-libgcc -static-libstdc++)
endif()
add_test(NAME guest_kernel_sys_pwrite COMMAND guest_kernel_sys_pwrite_tests ${UNPATCHED_DIR} unpatched)
add_test(NAME guest_kernel_sys_pwrite_patched COMMAND guest_kernel_sys_pwrite_tests ${PATCHED_DIR} patched)
set_tests_properties(guest_kernel_sys_pwrite guest_kernel_sys_pwrite_patched PROPERTIES TIMEOUT 20)
add_test_executable(guest_kernel_sys_tests tests/GuestKernelSys.cpp)
target_include_directories(guest_kernel_sys_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(guest_kernel_sys_tests PRIVATE libkernel_sys libSceNet libSceAmpr libkernel libc)
Expand Down
4 changes: 4 additions & 0 deletions core/libs/prx/libSceLibcInternal/UserContext.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#include "prx/libkernel/include/Api.hpp"
#include "prx/libSceLibcInternal/include/Api.hpp"
#include "prx/libc/include/GuestStacks.hpp"
#include "prx/libc/include/JumpBuffer.hpp"
#include "prx/libc/include/Shutdown.hpp"
#include "prx/libc/include/general/VabiMacros.hpp"
#include "prx/libkernel/System/include/UserContext.hpp"
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>

namespace {

Expand Down Expand Up @@ -98,6 +100,8 @@ void APS5_VABI makecontext_nid_postfix(UserUcontext* context, void (APS5_VABI* s
machine.rbx = reinterpret_cast<std::uint64_t>(stack);
machine.rsp = reinterpret_cast<std::uint64_t>(stack);
machine.rip = reinterpret_cast<std::uint64_t>(&Aps5MakecontextStart_nid_no_patch);
const auto identity = JumpBuffer::GuestContextCreate_nid_no_patch(machine.rsp);
std::memcpy(machine.spare, &identity, sizeof(identity));
GuestStacks::GuestStackRegister_nid_no_patch(context->stackPointer, context->stackSize);
}

Expand Down
2 changes: 1 addition & 1 deletion core/libs/prx/libSceNet/Export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1129,14 +1129,14 @@ int APS5_VABI sceNetSocketClose(int s) {
if (!GuestSocketIsOpen_nid_no_patch(s)) return fail(NET_EBADF);
return close_nid_postfix(s) == 0 ? 0 : fail(*__error_nid_postfix());
}
KernelReleaseSocketNumber_nid_no_patch(s);
if (native) {
#ifdef _WIN32
::shutdown(native->value, SD_BOTH);
#else
::shutdown(native->value, SHUT_RDWR);
#endif
}
KernelReleaseSocketNumber_nid_no_patch(s);
g_cv.NotifyAll();
return 0;
}
Expand Down
14 changes: 8 additions & 6 deletions core/libs/prx/libSceSsl/Export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,13 +433,14 @@ struct Session {
auto& session = *static_cast<Session*>(argument);
const auto chunk = static_cast<int>(std::min<std::size_t>(length, INT_MAX));
for (;;) {
#ifdef _WIN32
auto* owner = static_cast<KernelSocketPoll::NativeOwner*>(session.socketOwner.get());
const auto sent = owner && owner->transfer
? owner->transfer(owner, true, const_cast<unsigned char*>(buffer), chunk)
: ::send(static_cast<SOCKET>(session.socket), reinterpret_cast<const char*>(buffer), chunk, 0);
:
#ifdef _WIN32
::send(static_cast<SOCKET>(session.socket), reinterpret_cast<const char*>(buffer), chunk, 0);
#else
const auto sent = ::send(static_cast<int>(session.socket), buffer, static_cast<std::size_t>(chunk), MSG_NOSIGNAL);
::send(static_cast<int>(session.socket), buffer, static_cast<std::size_t>(chunk), MSG_NOSIGNAL);
#endif
if (sent >= 0) return static_cast<int>(sent);
const int error = HostError();
Expand All @@ -455,13 +456,14 @@ struct Session {
auto& session = *static_cast<Session*>(argument);
const auto chunk = static_cast<int>(std::min<std::size_t>(length, INT_MAX));
for (;;) {
#ifdef _WIN32
auto* owner = static_cast<KernelSocketPoll::NativeOwner*>(session.socketOwner.get());
const auto received = owner && owner->transfer
? owner->transfer(owner, false, buffer, chunk)
: ::recv(static_cast<SOCKET>(session.socket), reinterpret_cast<char*>(buffer), chunk, 0);
:
#ifdef _WIN32
::recv(static_cast<SOCKET>(session.socket), reinterpret_cast<char*>(buffer), chunk, 0);
#else
const auto received = ::recv(static_cast<int>(session.socket), buffer, static_cast<std::size_t>(chunk), 0);
::recv(static_cast<int>(session.socket), buffer, static_cast<std::size_t>(chunk), 0);
#endif
if (received >= 0) return static_cast<int>(received);
const int error = HostError();
Expand Down
1 change: 1 addition & 0 deletions core/libs/prx/libc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ target_sources(libc PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/FileAndHeap.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HostErrno.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/FileLock.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/DescriptorAccess.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/StdioExtras.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/StandardStreams.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/StreamPurge.cpp
Expand Down
3 changes: 3 additions & 0 deletions core/libs/prx/libc/include/Api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "prx/libc/include/GuestDirectory.hpp"
#include "prx/libc/include/GuestErrno.hpp"
#include "prx/libc/include/FileStream.hpp"
#include "prx/libc/include/JumpBuffer.hpp"
#include "prx/libc/include/exceptions/Unwind.hpp"
#include "prx/libc/include/exceptions/Runtime.hpp"
#include "prx/libc/include/LegacySignals.hpp"
Expand Down Expand Up @@ -1576,6 +1577,8 @@ int APS5_VABI dl_iterate_phdr_nid_postfix(int (*callback)(dl_phdr_info*, std::si

[[gnu::returns_twice]] int APS5_VABI setjmp_nid_postfix(std::uint64_t* buffer);
[[noreturn]] void APS5_VABI longjmp_nid_postfix(std::uint64_t* buffer, int value);
[[gnu::returns_twice]] int APS5_VABI _setjmp_nid_postfix(std::uint64_t* buffer);
[[noreturn]] void APS5_VABI _longjmp_nid_postfix(std::uint64_t* buffer, int value);

std::uint8_t APS5_VABI __atomic_load_1_nid_postfix(const volatile std::uint8_t* target, int);
std::uint16_t APS5_VABI __atomic_load_2_nid_postfix(const volatile std::uint16_t* target, int);
Expand Down
123 changes: 123 additions & 0 deletions core/libs/prx/libc/include/DescriptorAccess.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#ifndef CORE_LIBS_PRX_LIBC_INCLUDE_DESCRIPTORACCESS_HPP
#define CORE_LIBS_PRX_LIBC_INCLUDE_DESCRIPTORACCESS_HPP

#include <memory>
#include <mutex>
#include <cstdint>
#include <atomic>

extern "C" {
void FileStreamSetCloseHookForTest_nid_no_patch(void (*hook)(int, int));
bool FileStreamCloseHookActive_nid_no_patch();
void FileStreamCloseEventForTest_nid_no_patch(int descriptor, int event);
void DescriptorAccessInitialize_nid_no_patch(void* access, int descriptor);
void DescriptorAccessLock_nid_no_patch(void* access);
bool DescriptorAccessTryLock_nid_no_patch(void* access);
void DescriptorAccessUnlock_nid_no_patch(void* access);
bool DescriptorAccessReadOrWait_nid_no_patch(void* access);
void DescriptorAccessWake_nid_no_patch(void* access) noexcept;
bool DescriptorVersionUnchanged_nid_no_patch(const void* version);
void DescriptorAccessSnapshot_nid_no_patch(const void* access, void* version);
void DescriptorOperationInitialize_nid_no_patch(void* operation, void* access);
void DescriptorOperationDestroy_nid_no_patch(void* operation);
bool DescriptorOperationInterrupted_nid_no_patch();
void DescriptorWakeInitialize_nid_no_patch(void* registration);
void DescriptorWakeDestroy_nid_no_patch(void* registration);
}

class GuestDescriptorAccess {
struct State;
public:
class Version {
public:
bool Unchanged() const { return DescriptorVersionUnchanged_nid_no_patch(this); }
private:
friend class GuestDescriptorAccess;
friend bool DescriptorVersionUnchanged_nid_no_patch(const void* version);
friend void DescriptorAccessSnapshot_nid_no_patch(const void* access, void* version);
Version() = default;
std::shared_ptr<State> state;
std::uint64_t value = 0;
};
enum class Mode { Read, Change, Update, Close };
class Operation {
public:
explicit Operation(GuestDescriptorAccess& access) { DescriptorOperationInitialize_nid_no_patch(this, &access); }
~Operation() { DescriptorOperationDestroy_nid_no_patch(this); }
Operation(const Operation&) = delete;
Operation& operator=(const Operation&) = delete;
bool Interrupted() const { return interrupted.load(); }
static bool CurrentInterrupted() { return DescriptorOperationInterrupted_nid_no_patch(); }
class WakeRegistration {
public:
WakeRegistration(void (*interrupt)(void*) noexcept, void* argument)
: interrupt(interrupt), argument(argument) { DescriptorWakeInitialize_nid_no_patch(this); }
~WakeRegistration() { DescriptorWakeDestroy_nid_no_patch(this); }
WakeRegistration(const WakeRegistration&) = delete;
WakeRegistration& operator=(const WakeRegistration&) = delete;
private:
friend class Operation;
friend void DescriptorWakeInitialize_nid_no_patch(void* registration);
friend void DescriptorWakeDestroy_nid_no_patch(void* registration);
WakeRegistration* previous = nullptr;
Operation* operation = nullptr;
void (*interrupt)(void*) noexcept;
void* argument;
};
private:
friend struct State;
friend void DescriptorOperationInitialize_nid_no_patch(void* operation, void* access);
friend void DescriptorOperationDestroy_nid_no_patch(void* operation);
friend bool DescriptorOperationInterrupted_nid_no_patch();
friend void DescriptorWakeInitialize_nid_no_patch(void* registration);
friend void DescriptorWakeDestroy_nid_no_patch(void* registration);
static thread_local Operation* current;
std::shared_ptr<State> state;
Operation* previous = nullptr;
WakeRegistration* wake = nullptr;
std::atomic<bool> interrupted{false};
void Interrupt() noexcept;
};
GuestDescriptorAccess(int descriptor, Mode mode)
: GuestDescriptorAccess(descriptor, mode, std::defer_lock) { Lock(); }
GuestDescriptorAccess(int descriptor, Mode mode, std::defer_lock_t)
: mode(mode) { DescriptorAccessInitialize_nid_no_patch(this, descriptor); }
~GuestDescriptorAccess() { if (held) Unlock(); }
GuestDescriptorAccess(const GuestDescriptorAccess&) = delete;
GuestDescriptorAccess& operator=(const GuestDescriptorAccess&) = delete;
void Lock() { DescriptorAccessLock_nid_no_patch(this); }
bool TryLock() { return DescriptorAccessTryLock_nid_no_patch(this); }
void Unlock() { DescriptorAccessUnlock_nid_no_patch(this); }
bool ReadOrWait() { return DescriptorAccessReadOrWait_nid_no_patch(this); }
void Wake() noexcept { DescriptorAccessWake_nid_no_patch(this); }
Version Snapshot() const {
Version result;
DescriptorAccessSnapshot_nid_no_patch(this, &result);
return result;
}
static void LockTogether(GuestDescriptorAccess& first, GuestDescriptorAccess& second) {
struct Lockable {
GuestDescriptorAccess& access;
void lock() { access.Lock(); }
bool try_lock() { return access.TryLock(); }
void unlock() { access.Unlock(); }
} firstLock{first}, secondLock{second};
std::lock(firstLock, secondLock);
}

private:
friend void DescriptorAccessInitialize_nid_no_patch(void* access, int descriptor);
friend void DescriptorAccessLock_nid_no_patch(void* access);
friend bool DescriptorAccessTryLock_nid_no_patch(void* access);
friend void DescriptorAccessUnlock_nid_no_patch(void* access);
friend bool DescriptorAccessReadOrWait_nid_no_patch(void* access);
friend void DescriptorAccessWake_nid_no_patch(void* access) noexcept;
friend void DescriptorAccessSnapshot_nid_no_patch(const void* access, void* version);
friend void DescriptorOperationInitialize_nid_no_patch(void* operation, void* access);
static std::shared_ptr<State> Get(int descriptor);
std::shared_ptr<State> state;
Mode mode;
bool held = false;
};

#endif
61 changes: 57 additions & 4 deletions core/libs/prx/libc/include/FileStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <cstdint>
#include <cstddef>
#include <type_traits>
#include "prx/libc/include/DescriptorAccess.hpp"
#ifdef _WIN32
#include <io.h>
#include "prx/libc/include/FileLock.hpp"
Expand Down Expand Up @@ -43,9 +44,9 @@ class ClosingDescriptor {
public:
ClosingDescriptor([[maybe_unused]] std::FILE* stream, int descriptor)
#ifdef _WIN32
: _stream(stream), _closing(BeginClosingDescriptor_nid_no_patch(descriptor)) {}
: _stream(stream), _access(descriptor, GuestDescriptorAccess::Mode::Change), _closing(BeginClosingDescriptor_nid_no_patch(descriptor)) {}
#else
: _closing(BeginClosingDescriptor_nid_no_patch(descriptor)) {}
: _access(descriptor, GuestDescriptorAccess::Mode::Change), _closing(BeginClosingDescriptor_nid_no_patch(descriptor)) {}
#endif
~ClosingDescriptor() { EndClosingDescriptor_nid_no_patch(_closing); }
ClosingDescriptor(const ClosingDescriptor&) = delete;
Expand All @@ -61,6 +62,7 @@ class ClosingDescriptor {
std::FILE* stream;
} _stream;
#endif
GuestDescriptorAccess _access;
void* _closing;
};

Expand Down Expand Up @@ -89,7 +91,53 @@ static constexpr const char* FOPEN_MSG_OPEN_FAILED = "open failed";
extern "C" int KeepHostStandardError_nid_no_patch();
#endif

extern "C" bool TryLockNativeStream_nid_no_patch(std::FILE* stream);

class FileStream {
class NativeLock {
std::FILE* handle;
public:
explicit NativeLock(std::FILE* handle, bool closing = false) : handle(handle) {
if (!handle) return;
if (closing && FileStreamCloseHookActive_nid_no_patch()) {
#ifdef _WIN32
const bool acquired = TryLockNativeStream_nid_no_patch(handle);
const int descriptor = ::_fileno(handle);
#else
const bool acquired = ::ftrylockfile(handle) == 0;
const int descriptor = ::fileno(handle);
#endif
FileStreamCloseEventForTest_nid_no_patch(descriptor, acquired ? 3 : 2);
if (acquired) return;
}
#ifdef _WIN32
::_lock_file(handle);
#else
::flockfile(handle);
#endif
}
~NativeLock() {
if (!handle) return;
#ifdef _WIN32
::_unlock_file(handle);
#else
::funlockfile(handle);
#endif
}
NativeLock(const NativeLock&) = delete;
NativeLock& operator=(const NativeLock&) = delete;
void Forget() { handle = nullptr; }
void Retain(std::FILE* value) { handle = value; }
int Close() {
#ifdef _WIN32
const int result = ::_fclose_nolock(handle);
::_unlock_file(std::exchange(handle, nullptr));
return result;
#else
return std::fclose(std::exchange(handle, nullptr));
#endif
}
};
// Only the macro-accessed FreeBSD prefix is exposed. The remaining guest
// FILE area is reserved; host state lives beyond it and is never a guest FILE*.
GuestFilePrefix _guest{};
Expand Down Expand Up @@ -217,6 +265,7 @@ class FileStream {
return Adopt(open(filename, mode));
}
auto* previous = GetHandle();
NativeLock streamLock(previous, true);
_guest = {};
guestError = false;
randomDevice = false;
Expand All @@ -234,7 +283,7 @@ class FileStream {
if (open && !filename.empty()) {
if (!IsHostStandard()) {
_handle = nullptr;
std::fclose(previous);
streamLock.Close();
closing.reset();
_handle = open(filename, mode);
} else {
Expand Down Expand Up @@ -275,10 +324,13 @@ class FileStream {
KeepStandardHandle_nid_no_patch(replaced, standard);
#else
if (::fileno(previous) == 2) KeepHostStandardError_nid_no_patch();
const bool hostStandard = IsHostStandard();
const ClosingDescriptor closing(previous, ::fileno(previous));
const int kept = IsHostStandard() ? DuplicateHostDescriptor_nid_no_patch(::fileno(previous)) : -1;
if (kept >= 0) ::flockfile(previous);
if (!hostStandard) streamLock.Forget();
_handle = std::freopen(filename.c_str(), mode, previous);
if (!hostStandard && _handle) streamLock.Retain(_handle);
if (kept >= 0) RestoreHostStandard(previous, kept);
#endif
return Adopt(_handle);
Expand Down Expand Up @@ -438,14 +490,15 @@ class FileStream {

int Close() {
GetHandle();
NativeLock streamLock(_handle, true);
#ifdef _WIN32
GuestFileLockForget_nid_no_patch(::_fileno(_handle));
if (std::exchange(directory, false)) ForgetDirectoryStream_nid_no_patch(::_fileno(_handle));
const ClosingDescriptor closing(_handle, ::_fileno(_handle));
#else
const ClosingDescriptor closing(_handle, ::fileno(_handle));
#endif
const int result = std::fclose(_handle);
const int result = streamLock.Close();
_handle = nullptr;
_guest.flags = 0;
_guest.descriptor = -1;
Expand Down
Loading
Loading