From 5b158b163d3d23e4702f86525f40063111b75cec Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 31 Aug 2026 08:09:06 +0800 Subject: [PATCH 1/2] =?UTF-8?q?0.11.0=20=E2=80=94=20openkal=200.12.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No behaviour changes. The specification's 0.12 additions are prose: clause 11 entry 9 now names what handles-do-not-cross costs a caller composing job control, and the two file-creating operations point at entry 6. This implementation already satisfied both. --- mcpp.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mcpp.toml b/mcpp.toml index 8cba798..95f036c 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-linux" -version = "0.10.0" +version = "0.11.0" description = "The reference implementation of openkal for Linux, written on the kernel's own system-call interface so that it can be placed beneath a C library as well as above one." license = "Apache-2.0" @@ -18,7 +18,7 @@ authors = ["mcpplibs"] repo = "https://github.com/mcpplibs/openkal-linux" [dependencies] -openkal = "0.11.0" +openkal = "0.12.0" # The package contributes definitions and no modules. The interface it # implements is declared by the specification package, which this package From 2fa1235d8aa04fb71e2685d0d87ac9464fb6960a Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Mon, 31 Aug 2026 08:34:26 +0800 Subject: [PATCH 2/2] Examine whether the disposition was installed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠️ The same defect as openkal-macos, and this one SHIPPED --- in 0.11, where this operation was added. The result of installing the disposition was discarded, so an installation that failed would have handed the caller a word that can never change. Found by writing the same code for the other kernel, where the trampoline made the failure mode impossible to overlook. The suite conforms in 181 observations with the change. --- src/process.cpp | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/process.cpp b/src/process.cpp index a265064..66a70ae 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -486,15 +486,22 @@ void stop_handler(int) { 1 /* FUTEX_WAKE */, 0x7fffffff, 0, 0, 0); } -void arm_one(int signo) { +// ⚠️ THE RESULT IS EXAMINED, AND IT WAS NOT WHEN THIS SHIPPED IN 0.11. An +// installation that failed would leave a word that can never change, and +// answering the caller with one is `reporting success having done nothing' in +// its exact form: the program asks whether its end has been requested, is told +// no, and goes on being told no after it has been. Found reviewing the same +// code written for the other kernel, where the trampoline made the failure +// mode obvious. +bool arm_one(int signo) { struct { void* handler; unsigned long flags; void* restorer; unsigned long mask; } act {}; act.handler = reinterpret_cast(&stop_handler); #if defined(__x86_64__) act.flags = sa_restorer_flag; act.restorer = reinterpret_cast(&okl_sigreturn_trampoline); #endif - okl::sys(okl::nr_rt_sigaction, signo, - reinterpret_cast(&act), 0, sizeof act.mask); + return !okl::failed(okl::sys(okl::nr_rt_sigaction, signo, + reinterpret_cast(&act), 0, sizeof act.mask)); } } // namespace @@ -504,11 +511,15 @@ void arm_one(int signo) { // this operation expects --- and it is the only arrangement under which adding // this operation changes nothing for anyone who does not use it. const kal_u32* kal_process_stop_requested(void) { - if (!__atomic_exchange_n(&g_stop_armed, 1, __ATOMIC_ACQ_REL)) { - arm_one(15); // SIGTERM - arm_one(2); // SIGINT + // ⚠️ THREE STATES AND NOT TWO: not yet tried, armed, refused. A second + // caller is told what the first found rather than arming again. + int state = __atomic_load_n(&g_stop_armed, __ATOMIC_ACQUIRE); + if (state == 0) { + const bool ok = arm_one(15) && arm_one(2); // SIGTERM, SIGINT + state = ok ? 1 : -1; + __atomic_store_n(&g_stop_armed, state, __ATOMIC_RELEASE); } - return &g_stop_word; + return state == 1 ? &g_stop_word : nullptr; } kal_uintptr kal_process_props(void) { @@ -517,7 +528,13 @@ kal_uintptr kal_process_props(void) { | KAL_PROCESS_PROP_CHANNEL | KAL_PROCESS_PROP_GRANT_DIR | KAL_PROCESS_PROP_BOUND_LIFETIME | KAL_PROCESS_PROP_JOB - | KAL_PROCESS_PROP_STOP_REQUESTED; + // ⚠️ AGREES WITH `kal_process_stop_requested', because the header + // defines null there as the absence this position reports. Read and + // never armed: asking what an implementation can do must not install a + // disposition, so the position is claimed until an installation has + // actually been refused. + | (__atomic_load_n(&g_stop_armed, __ATOMIC_ACQUIRE) == -1 + ? 0u : KAL_PROCESS_PROP_STOP_REQUESTED); } }