From 2b93aabdfdf79c4e2db0b83dc3afb73332fb018c Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Sun, 8 Nov 2026 02:09:40 +0900 Subject: [PATCH 1/5] 0.4.0: a platform question for a native build and an image alike; the platform modules in an image can_run_on(p) and on

(f) beside is_; R5 revised: a platform module is defined where it can be answered, a native build of its platform and an image that asks the system it runs upon (translator, elevated, on_dev_drive, effective_user; translated is false). tests/facts_test runs the questions on every row, natively and as images. Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com> --- .gitignore | 1 + CHANGELOG.md | 28 ++++++++++ README.md | 55 +++++++++++++++--- checks/discarded/src/main.cpp | 5 ++ checks/emscripten/tests/facts_test.cpp | 6 ++ checks/hosted/tests/facts_test.cpp | 6 ++ mcpp.toml | 11 ++-- src/openkal/macos.cpp | 15 +++++ src/openkal/posix.cpp | 57 +++++++++++++++++++ src/openkal/windows.cpp | 77 ++++++++++++++++++++++++++ src/platform.cppm | 32 +++++++++++ tests/facts_test.cpp | 43 ++++++++++++++ 12 files changed, 325 insertions(+), 11 deletions(-) create mode 100644 checks/emscripten/tests/facts_test.cpp create mode 100644 checks/hosted/tests/facts_test.cpp create mode 100644 src/openkal/macos.cpp create mode 100644 src/openkal/posix.cpp create mode 100644 src/openkal/windows.cpp create mode 100644 tests/facts_test.cpp diff --git a/.gitignore b/.gitignore index 08360ef..6c879f0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ compile_commands.json *.log mcpp.lock +.mcpp/ diff --git a/CHANGELOG.md b/CHANGELOG.md index be00d97..95b6922 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,33 @@ # Changelog +## 0.4.0 + +- **A platform question for a native build and an image alike.** `can_run_on(p)` + says whether this build can run on `p` (a native build on its own system, an + image on every system a loader runs upon), and `on

(f)` runs `f` when the + build runs on `P` now. `if constexpr (can_run_on(P))` keeps another system's + platform module out of a native build, as `if constexpr (is_)` does; + `host()` then decides in an image, where `is_` is false and a branch + under it never runs. `on

` takes the platform as an argument, so its body is + a template a build that cannot run on `P` never instantiates; a lambda without + the parameter is refused. `is_` keeps its meaning: a native build of + that platform (README, "A platform question"). +- **The platform modules in an image (R5 as revised).** A platform module is + defined where it can be answered: in a native build of its platform, and in an + image where the image can ask the system it runs upon. `linux::translator()` + reads /proc as on Linux; `windows::elevated()` reads the integrity level + `whoami /groups` lists, by SID; `windows::on_dev_drive()` asks `fsutil devdrv + query`; `posix::effective_user()` reads /proc on Linux and `/usr/bin/id -u` on + macOS; `macos::translated()` is `false`, since macOS runs images through an + aarch64 okrun only. The system's programs are started by absolute name with a + bound of ten seconds, and each answer is asked once. The code pages, long + names, the registry, the writable drives and the creation mask remain + undefined in an image: okrun carries an image's streams and names, and the + others belong to a native installation. Before 0.4.0 an image defined no + platform module, and a program shipped as an image that guarded them with + `if constexpr (is_)` lost them without a word (mcpp-community/mcpp + design 2026-11-08, S2 and S3). + ## 0.3.1 - **A name in the long spelling is the name it spells.** `fs::extended` writes diff --git a/README.md b/README.md index cb7ff0f..87e48ef 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ with compile-time platform constants and a few platform modules. ```toml [dependencies] -os = { namespace = "mcpplibs", version = "0.3.1" } +mcpplibs.os = "0.4.0" ``` ```cpp @@ -106,7 +106,7 @@ dropped (0.2.8). | Module | Contents | |---|---| -| `mcpplibs.os.platform` | `PLATFORM`, `ARCH`, `is_linux` / `is_macos` / `is_windows` / `is_posix` / `is_emscripten`, `exe_suffix`, `path_list_separator`; `host()`, a constant expression on a native target | +| `mcpplibs.os.platform` | `PLATFORM`, `ARCH`, `is_linux` / `is_macos` / `is_windows` / `is_posix` / `is_emscripten`, `exe_suffix`, `path_list_separator`; `host()`, a constant expression on a native target; `can_run_on(p)` and `on

(f)`, a platform question that holds in a native build and an image alike | | `mcpplibs.os.error` | `errc` (openkal's closed set of conditions), `error`, `result` | | `mcpplibs.os.env` | variables (names without case on Windows), `NAME=value` entries as overrides (`assignments`), arguments, the program's own image, lists of directories in the host's separator (`split_list`, `join_list`), PATH search with PATHEXT | | `mcpplibs.os.fs` | `write_atomic`, `publish` (no replace), `append`, `sync`, `caps`, `lock`, links, `set_executable`, `stamp_of`, `identity_of`, `owner_of`, `writable`, `locate`, `absolute`, `names_a_place`, `canonical`, a bounded `read`; what a volume does, measured (`measure`, `volume_type`), and the operations that follow it (`place`, `exchange`); names in the host's rules without the file system: `generic`, `native`, `extended`, `is_absolute`, `same`, `within` | @@ -120,7 +120,7 @@ dropped (0.2.8). | `mcpplibs.os.machine` | the machine's architecture (through Rosetta and WoW64), memory and the memory available now, processors (logical, physical, of differing speed) | | `mcpplibs.os.random` | bytes from the system's source of unpredictable bytes; `hex` | | `mcpplibs.os.library` | shared libraries at run time: `open` (a path or a name the system searches for), `loaded` (one the process has, without loading it), a handle's `symbol` / `function`, `process_symbol` (as the loader resolves one), `suffix` | -| `mcpplibs.os.linux` / `.macos` / `.windows` / `.posix` | platform modules: declared on every target, defined only on their own | +| `mcpplibs.os.linux` / `.macos` / `.windows` / `.posix` | platform modules: declared on every target, defined on their own and, where an image can answer, in an image | ## Rules @@ -133,9 +133,10 @@ dropped (0.2.8). - in an image (`-openkal`) it is an ordinary function, and using it in a constant expression is a compile error. - **R4.** A native handle does not appear in a portable type. -- **R5.** A platform module is declared on every target and defined only on its own. A call - outside `if constexpr` for that platform is a link error. The same call in a discarded branch - is not an odr-use, so it links. CI asserts both. +- **R5.** A platform module is declared on every target and defined where it can be answered: in + a native build of its own platform, and in an image where the image can ask the system it runs + upon (0.4.0). Elsewhere a call outside `if constexpr` is a link error. The same call in a + discarded branch is not an odr-use, so it links. CI asserts both. - **R6.** Where openkal is not in its shared form, this package's resources do not cross a shared-object boundary. - **R7.** A name reaches the system as UTF-8 and comes back as UTF-8 on every host, never @@ -145,11 +146,51 @@ dropped (0.2.8). nothing else. The tests write, read and rename names in four scripts. Interface units import `std` and contain no system header and no macro. Implementation units -on openkal import only `openkal.*`. The Windows and macOS units declare the functions they +on openkal import only `openkal.*` and this package's own modules. The Windows and macOS units declare the functions they call themselves (`src/windows/win32.h`, `src/macos/darwin.h`). Linux's and macOS's kernel calls are in `src/linux/arch/` and `src/macos/arch/`, which the manifest selects by architecture. +## A platform question, in a native build and an image + +Two questions are asked of the platform, and each has its form: + +| Question | Form | Native build | Image | +|---|---|---|---| +| Is this a native build for the platform? | `if constexpr (os::is_windows)` | a constant | `false` | +| Does this build run on the platform now? | `if constexpr (os::can_run_on(P))` with `if (os::host() == P)`, or `os::on

([&](auto) { ... })` | a constant; another system's branch is discarded | known when the image is loaded | + +The first is right for code that belongs to a native build alone: a console's code page set +for the C library's narrow functions has no meaning in an image, whose streams okrun carries. +The second is right for code that is to take effect wherever the program runs, which is what a +program shipped as an image needs: + +```cpp +if constexpr (os::can_run_on(os::platform::windows)) + if (os::host() == os::platform::windows) + onDevDrive = os::windows::on_dev_drive(cache); + +os::on([&](auto) { sandbox = os::linux::translator().value_or(""); }); +``` + +`on

` takes the platform as a parameter, so the body is a template and a build that cannot +run on `P` never instantiates it; a lambda without the parameter is refused, because its body +would name another system's module on every build. The platform modules in an image: + +| Function | In an image | +|---|---| +| `linux::translator()` | `/proc/self/status`, the tracer's `comm` and the environment, as on Linux | +| `windows::elevated()` | the integrity level `whoami /groups` lists (SID `S-1-16-12288` or `S-1-16-16384`) | +| `windows::on_dev_drive()` | `fsutil devdrv query `; not known when the tool answers in another language or refuses | +| `posix::effective_user()` | `/proc/self/status` on Linux, `/usr/bin/id -u` on macOS; the largest number when neither answers | +| `macos::translated()` | `false`: macOS runs images through an aarch64 okrun only | +| `windows::code_page()`, `console_output_code_page()`, `long_paths_enabled()`, `machine_registry_path()`, `writable_fixed_drive()`, `posix::set_creation_mask()` | not defined: okrun carries an image's streams and names, and the others belong to a native installation | + +The system's programs are started by absolute name (`%SystemRoot%\System32`, `/usr/bin`), with a +bound of ten seconds, and each answer is asked once per process. `host()` decides which system's +question applies, which is that system's convention; whether a program can be started is +openkal's capability and is answered by the start itself (openkal SPEC clause 30). + ## As an ok image Built for `-openkal` (openkal SPEC clause 12), a program over this library diff --git a/checks/discarded/src/main.cpp b/checks/discarded/src/main.cpp index e2fcb12..9d91158 100644 --- a/checks/discarded/src/main.cpp +++ b/checks/discarded/src/main.cpp @@ -13,5 +13,10 @@ int main() { if constexpr (os::is_linux) n += static_cast(os::linux::translator().has_value()); if constexpr (os::is_macos) n += static_cast(os::macos::translated()); if constexpr (os::is_windows) n += static_cast(os::windows::elevated()); + // The same calls in the form that also holds in an image (0.4.0). + if constexpr (os::can_run_on(os::platform::linux)) + if (os::host() == os::platform::linux) n += static_cast(os::linux::translator().has_value()); + os::on([&](auto) { n += static_cast(os::macos::translated()); }); + os::on([&](auto) { n += static_cast(os::windows::elevated()); }); return n >= 0 ? 0 : 1; } diff --git a/checks/emscripten/tests/facts_test.cpp b/checks/emscripten/tests/facts_test.cpp new file mode 100644 index 0000000..036c979 --- /dev/null +++ b/checks/emscripten/tests/facts_test.cpp @@ -0,0 +1,6 @@ +// facts_test.cpp of mcpplibs.os, compiled in this arrangement. The imports are restated +// because the dependency scan reads this file and not the one it includes. +#include "../../../tests/check.hpp" +import std; +import mcpplibs.os; +#include "../../../tests/facts_test.cpp" diff --git a/checks/hosted/tests/facts_test.cpp b/checks/hosted/tests/facts_test.cpp new file mode 100644 index 0000000..036c979 --- /dev/null +++ b/checks/hosted/tests/facts_test.cpp @@ -0,0 +1,6 @@ +// facts_test.cpp of mcpplibs.os, compiled in this arrangement. The imports are restated +// because the dependency scan reads this file and not the one it includes. +#include "../../../tests/check.hpp" +import std; +import mcpplibs.os; +#include "../../../tests/facts_test.cpp" diff --git a/mcpp.toml b/mcpp.toml index bf627a8..a6407b6 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "os" -version = "0.3.1" +version = "0.4.0" description = "mcpplibs.os: a C++ operating-system library over openkal --- processes, files, environment, terminals, directories and local IPC, with compile-time platform constants and a few platform modules." license = "Apache-2.0" authors = ["mcpplibs"] @@ -108,10 +108,13 @@ sources = ["src/windows/posix/stdio.cpp"] sources = ["src/targets/emscripten.cppm", "src/emscripten/*.cpp", "src/posix/fs.cpp"] # AN OK IMAGE (`-openkal', openkal SPEC clause 12): no implementation -# beneath --- the loader binds the image's `kal_*' --- and no platform module -# defined. `host()' and the conventions are answered when the image is loaded. +# beneath --- the loader binds the image's `kal_*' --- and the platform modules +# defined where an image can answer them (R5 as revised in 0.4.0): Linux's +# translator from /proc, Windows' token and developer volume and the POSIX +# effective user from the system's own programs, macOS' translation as never. +# `host()' and the conventions are answered when the image is loaded. [target.'cfg(os = "openkal")'.build] -sources = ["src/targets/openkal.cppm", "src/openkal/*.cpp"] +sources = ["src/targets/openkal.cppm", "src/openkal/*.cpp", "src/linux/linux.cpp"] # The C library, the C++ run-time and the loader of an image are its # platform's: mcpp 2026.10.27.1 and later select openkal-platform for diff --git a/src/openkal/macos.cpp b/src/openkal/macos.cpp new file mode 100644 index 0000000..b249cbf --- /dev/null +++ b/src/openkal/macos.cpp @@ -0,0 +1,15 @@ +// mcpplibs.os.macos in an ok image (0.4.0): never translated. macOS runs +// images through an okrun of its own architecture only (aarch64; there is no +// x86-64 okrun for macOS), so an image there is never run by Rosetta. When an +// x86-64 okrun exists, the answer is "an x86-64 image on a machine with +// `hw.optional.arm64'"; `sysctl.proc_translated' would answer for the sysctl +// program asked, not for the image. +module mcpplibs.os.macos; + +import std; + +namespace mcpplibs::os::macos { + +bool translated() { return false; } + +} // namespace mcpplibs::os::macos diff --git a/src/openkal/posix.cpp b/src/openkal/posix.cpp new file mode 100644 index 0000000..8ffc150 --- /dev/null +++ b/src/openkal/posix.cpp @@ -0,0 +1,57 @@ +// mcpplibs.os.posix in an ok image (0.4.0): the effective user, asked of the +// system the image runs upon. The creation mask is a state of the process that +// openkal does not expose, and remains undefined in an image. +module mcpplibs.os.posix; + +import std; +import mcpplibs.os.platform; +import mcpplibs.os.process; + +namespace mcpplibs::os::posix { + +namespace { + +// The second number of the `Uid:' line of /proc/self/status, the effective one. +std::optional from_status() { + std::ifstream in("/proc/self/status", std::ios::binary); + for (std::string line; std::getline(in, line);) { + if (!line.starts_with("Uid:")) continue; + std::istringstream fields(line.substr(4)); + std::uint32_t real = 0, effective = 0; + if (fields >> real >> effective) return effective; + } + return std::nullopt; +} + +std::optional from_id() { + process::spawn_options o; + o.program = "/usr/bin/id"; + o.args = {"-u"}; + o.in = process::stdio::null; + o.err = process::stdio::null; + process::bounds limits; + limits.hard = std::chrono::seconds{10}; + auto r = process::run(std::move(o), limits); + if (!r || !r->status.success()) return std::nullopt; + std::uint32_t v = 0; + const auto& s = r->out; + const auto [end, ec] = std::from_chars(s.data(), s.data() + s.size(), v); + if (ec != std::errc{} || end == s.data()) return std::nullopt; + return v; +} + +} // namespace + +// Not known -- not a POSIX system, or neither source answered -- is the largest +// number, which names no user. +std::uint32_t effective_user() { + static const std::uint32_t answer = [] { + std::optional v; + if (host() == platform::linux) v = from_status(); + if (!v && (host() == platform::linux || host() == platform::macos)) v = from_id(); + return v.value_or(std::numeric_limits::max()); + }(); + return answer; +} + +} // namespace mcpplibs::os::posix diff --git a/src/openkal/windows.cpp b/src/openkal/windows.cpp new file mode 100644 index 0000000..a0cd86f --- /dev/null +++ b/src/openkal/windows.cpp @@ -0,0 +1,77 @@ +// mcpplibs.os.windows in an ok image (0.4.0, R5 as revised): an image reaches +// no Win32 function (it loads no library of the system, openkal SPEC clause +// 12), so what it answers it asks a program of the system for. Only the facts +// a program of Windows reports are defined here; the code pages, long names, +// the registry and the drives a user writes to are okrun's affair or the +// native build's, and remain undefined in an image (a use is a link error). +// +// `host()' decides which system's question applies, which is a convention of +// that system and not a capability of openkal's implementation (SPEC clause +// 30); whether a program can be started at all is openkal's capability, and a +// refusal is answered as "not known". +module mcpplibs.os.windows; + +import std; +import mcpplibs.os.platform; +import mcpplibs.os.env; +import mcpplibs.os.process; + +namespace mcpplibs::os::windows { + +namespace { + +// `%SystemRoot%\System32\.exe', never a name looked for on PATH. +std::optional system_tool(std::string_view tool) { + auto root = env::get("SystemRoot"); + if (!root || root->empty()) return std::nullopt; + std::string name(tool); + name += ".exe"; + return std::filesystem::path(*root) / "System32" / name; +} + +// What the tool printed, when it ran to an end with status 0. +std::optional printed(std::string_view tool, std::vector args) { + auto program = system_tool(tool); + if (!program) return std::nullopt; + process::spawn_options o; + o.program = *program; + o.args = std::move(args); + o.in = process::stdio::null; + o.err = process::stdio::null; + process::bounds limits; + limits.hard = std::chrono::seconds{10}; + auto r = process::run(std::move(o), limits); + if (!r || r->timed_out || !r->status.success()) return std::nullopt; + return std::move(r->out); +} + +} // namespace + +// The token's integrity level as `whoami /groups' lists it: High (S-1-16-12288) +// or System (S-1-16-16384) is the administrator's token. A SID, not a group's +// name, so the answer does not depend on the system's language. +bool elevated() { + if (host() != platform::windows) return false; + static const bool answer = [] { + const auto text = printed("whoami", {"/groups"}); + return text && (text->find("S-1-16-12288") != std::string::npos + || text->find("S-1-16-16384") != std::string::npos); + }(); + return answer; +} + +// `fsutil devdrv query ' names a developer volume as one; its answer is +// read only when the tool states one of its two sentences, and is otherwise +// not known (a system in another language, or a user the tool refuses). +std::optional on_dev_drive(const std::filesystem::path& directory) { + if (host() != platform::windows) return std::nullopt; + const auto text = directory.generic_string(); + if (text.size() < 2 || text[1] != ':') return std::nullopt; + const auto said = printed("fsutil", {"devdrv", "query", text.substr(0, 2)}); + if (!said) return std::nullopt; + if (said->find("not a developer volume") != std::string::npos) return false; + if (said->find("developer volume") != std::string::npos) return true; + return std::nullopt; +} + +} // namespace mcpplibs::os::windows diff --git a/src/platform.cppm b/src/platform.cppm index e7627e3..73765fb 100644 --- a/src/platform.cppm +++ b/src/platform.cppm @@ -32,6 +32,38 @@ inline constexpr bool is_image = PLATFORM == platform::openkal; // streams are the host's. inline constexpr bool is_emscripten = PLATFORM == platform::emscripten; +// WHERE THIS BUILD CAN RUN, AND WHERE IT RUNS (0.4.0). `is_' says +// what the build is for: a native build of that system. A program that is +// also built as an image asks two questions instead -- can this build run on +// the platform (a constant: a native build runs on its own system, an image +// on every system a loader runs upon), and does it run there now (`host()', +// a constant on a native build and known when an image is loaded): +// +// if constexpr (os::can_run_on(os::platform::windows)) +// if (os::host() == os::platform::windows) +// on_drive = os::windows::on_dev_drive(dir); +// +// The first is what keeps another system's platform module out of a native +// build (a discarded statement is no odr-use, R5); the second is what an image +// decides by. +constexpr bool can_run_on(platform p) noexcept { + if constexpr (is_image) return p == platform::linux || p == platform::macos || p == platform::windows; + else return PLATFORM == p; +} + +// The two questions for one call: `f' runs when this build runs on `P' now. +// `f' takes the platform as an argument (`[&](auto) { ... }'), which makes its +// body a template: a build that cannot run on `P' never instantiates it, so a +// platform module named inside is no odr-use there. A lambda without the +// parameter does not satisfy the constraint, because its body would be an +// odr-use of what it names on every build. +template + requires std::invocable> +void on(F&& f) { + if constexpr (can_run_on(P)) + if (host() == P) std::invoke(f, std::integral_constant{}); +} + // The name of a platform, as mcpp's target vocabulary and openkal's // `kal_env_system' spell it. constexpr std::string_view name(platform p) noexcept { diff --git a/tests/facts_test.cpp b/tests/facts_test.cpp new file mode 100644 index 0000000..10102fc --- /dev/null +++ b/tests/facts_test.cpp @@ -0,0 +1,43 @@ +// The platform modules where this build runs (0.4.0): the same questions in a +// native build and an image, asked through `on

', so that this one source +// links and answers on every row. The values are the CI runners': Windows +// runs elevated, Linux runs under no translator, macOS runs images natively. +#include "check.hpp" +import std; +import mcpplibs.os; + +namespace os = mcpplibs::os; + +static_assert(os::can_run_on(os::PLATFORM) || os::is_image, "a native build runs on its own system"); +static_assert(!os::can_run_on(os::platform::openkal), "an image is a target, never a system it runs upon"); +static_assert(!os::can_run_on(os::platform::emscripten) || os::is_emscripten, "no image runs under Emscripten"); +static_assert(!os::is_image || (os::can_run_on(os::platform::linux) && os::can_run_on(os::platform::macos) + && os::can_run_on(os::platform::windows)), + "an image can run on every system a loader runs upon"); + +int main() { + const bool ci = os::env::get("GITHUB_ACTIONS").has_value(); + int asked = 0; + os::on([&](auto) { + ++asked; + check(!os::linux::translator().has_value() || !ci, "Linux: the runner is no translator"); + const auto uid = os::posix::effective_user(); + auto id = os::process::run({.program = "/usr/bin/id", .args = {"-u"}, .err = os::process::stdio::null}); + check(id && std::to_string(uid) == std::string(id->out.substr(0, id->out.find_first_of("\r\n"))), + "Linux: the effective user is the one `id -u' names"); + }); + os::on([&](auto) { + ++asked; + check(!os::macos::translated() || !os::is_image, "macOS: an image is never translated"); + check(os::posix::effective_user() != std::numeric_limits::max(), "macOS: the effective user is known"); + }); + os::on([&](auto) { + ++asked; + check(os::windows::elevated() || !ci, "Windows: the runner's token is the administrator's"); + const auto dev = os::windows::on_dev_drive(std::filesystem::current_path()); + std::printf(" note on_dev_drive(cwd) = %s\n", dev ? (*dev ? "true" : "false") : "not known"); + check(!dev.value_or(false) || !ci, "Windows: the runner's work directory is on no developer volume"); + }); + check(asked == (os::is_emscripten ? 0 : 1), "exactly one platform answers where the build runs"); + return g_failures; +} From 6bf51cd6d83f3129d8ede47510aceef6c02f0201 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Sun, 8 Nov 2026 02:35:08 +0900 Subject: [PATCH 2/5] ci: images and the hosted arrangement over openkal-platform 0.24.3; facts_test names both answers Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com> --- .github/workflows/ci.yml | 18 ++++++++++-------- checks/hosted/mcpp.toml | 2 +- tests/facts_test.cpp | 5 +++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7ff9eaa..e421dad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -225,10 +225,11 @@ jobs: timeout-minutes: 120 env: # openkal 0.24.0, which this release is written against, in the group of - # openkal-platform 0.24.2, whose C++ run-time keeps the volume of a - # normalized name (openkal-llvm-runtime 0.19.2); the long-spelling tests - # of 0.3.1 need it on Windows. - MCPP_PLATFORM: openkal-platform@0.24.2 + # openkal-platform 0.24.3: its C++ run-time keeps the volume of a + # normalized name (openkal-llvm-runtime 0.19.2, which the long-spelling + # tests of 0.3.1 need on Windows), and its tools are openkal-ld and + # openkal-run 0.5.2, which the graph resolves since they were published. + MCPP_PLATFORM: openkal-platform@0.24.3 defaults: run: shell: bash @@ -278,10 +279,11 @@ jobs: timeout-minutes: 45 env: # openkal 0.24.0, which this release is written against, in the group of - # openkal-platform 0.24.2, whose C++ run-time keeps the volume of a - # normalized name (openkal-llvm-runtime 0.19.2); the long-spelling tests - # of 0.3.1 need it on Windows. - MCPP_PLATFORM: openkal-platform@0.24.2 + # openkal-platform 0.24.3: its C++ run-time keeps the volume of a + # normalized name (openkal-llvm-runtime 0.19.2, which the long-spelling + # tests of 0.3.1 need on Windows), and its tools are openkal-ld and + # openkal-run 0.5.2, which the graph resolves since they were published. + MCPP_PLATFORM: openkal-platform@0.24.3 strategy: fail-fast: false matrix: diff --git a/checks/hosted/mcpp.toml b/checks/hosted/mcpp.toml index f0f0705..655bb2a 100644 --- a/checks/hosted/mcpp.toml +++ b/checks/hosted/mcpp.toml @@ -13,7 +13,7 @@ version = "0.1.0" os = { path = "../.." } [target.'cfg(any(linux, macos, windows))'] -platform = "openkal-platform@0.24.2" +platform = "openkal-platform@0.24.3" # The tests are the package's own, each reached by an include from # tests/.cpp here (a test program is a file of the package that runs it). diff --git a/tests/facts_test.cpp b/tests/facts_test.cpp index 10102fc..5465355 100644 --- a/tests/facts_test.cpp +++ b/tests/facts_test.cpp @@ -23,8 +23,9 @@ int main() { check(!os::linux::translator().has_value() || !ci, "Linux: the runner is no translator"); const auto uid = os::posix::effective_user(); auto id = os::process::run({.program = "/usr/bin/id", .args = {"-u"}, .err = os::process::stdio::null}); - check(id && std::to_string(uid) == std::string(id->out.substr(0, id->out.find_first_of("\r\n"))), - "Linux: the effective user is the one `id -u' names"); + const std::string named = id ? std::string(id->out.substr(0, id->out.find_first_of("\r\n"))) : "(id did not run)"; + std::printf(" note effective_user() = %u, id -u = %s\n", uid, named.c_str()); + check(std::to_string(uid) == named, "Linux: the effective user is the one `id -u' names"); }); os::on([&](auto) { ++asked; From ee1d71e614beefae43ea75197cef898f87ec4bd9 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Sun, 8 Nov 2026 02:45:29 +0900 Subject: [PATCH 3/5] posix: the effective user and the creation mask by the kernel's calls, not the C library's openkal-musl's geteuid is the constant 1000 and it has no umask, so the hosted arrangement answered 1000 for every user (CI runner user 1001). Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com> --- CHANGELOG.md | 8 ++++++++ src/linux/arch/aarch64.cpp | 7 ++++++- src/linux/arch/riscv64.cpp | 7 ++++++- src/linux/arch/x86_64.cpp | 7 ++++++- src/macos/arch/aarch64.cpp | 7 ++++++- src/macos/arch/x86_64.cpp | 7 ++++++- src/posix/kernel.h | 9 ++++++++- src/posix/posix.cpp | 10 ++++++---- tests/facts_test.cpp | 24 ++++++++++++++++-------- 9 files changed, 68 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95b6922..f452440 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,14 @@ platform module, and a program shipped as an image that guarded them with `if constexpr (is_)` lost them without a word (mcpp-community/mcpp design 2026-11-08, S2 and S3). +- **The user and the creation mask are the kernel's.** On Linux and macOS + `posix::effective_user()` and `posix::set_creation_mask()` make the kernel's + own calls (src/posix/kernel.h), as the descriptors and the signals already + did. In the hosted arrangement the C library is openkal-musl, which sits on + openkal: openkal names no user, so its `geteuid` answers the constant 1000, + and it has no `umask`. The answer was then 1000 for every user, and a mask + was set nowhere; it is now the process's under every C library. Measured on + the CI runners (user 1001) and under `unshare -r` (user 0). ## 0.3.1 diff --git a/src/linux/arch/aarch64.cpp b/src/linux/arch/aarch64.cpp index c633d96..900f10e 100644 --- a/src/linux/arch/aarch64.cpp +++ b/src/linux/arch/aarch64.cpp @@ -28,7 +28,8 @@ constexpr long nr_write = 64, nr_uname = 160, nr_sysinfo = 179, nr_statfs = 43, - nr_renameat2 = 276; + nr_renameat2 = 276, + nr_geteuid = 175, nr_umask = 166; constexpr long f_dupfd_cloexec = 1030, sig_unblock = 1; @@ -61,6 +62,10 @@ void raise_signal(int signal) { call(nr_kill, call(nr_getpid), signal); } +unsigned effective_user() { return static_cast(call(nr_geteuid)); } + +unsigned creation_mask(unsigned mask) { return static_cast(call(nr_umask, static_cast(mask))); } + } // namespace mcpplibs::os::kernel namespace mcpplibs::os::linux_kernel { diff --git a/src/linux/arch/riscv64.cpp b/src/linux/arch/riscv64.cpp index 323a5c9..c578871 100644 --- a/src/linux/arch/riscv64.cpp +++ b/src/linux/arch/riscv64.cpp @@ -28,7 +28,8 @@ constexpr long nr_write = 64, nr_uname = 160, nr_sysinfo = 179, nr_statfs = 43, - nr_renameat2 = 276; + nr_renameat2 = 276, + nr_geteuid = 175, nr_umask = 166; constexpr long f_dupfd_cloexec = 1030, sig_unblock = 1; @@ -61,6 +62,10 @@ void raise_signal(int signal) { call(nr_kill, call(nr_getpid), signal); } +unsigned effective_user() { return static_cast(call(nr_geteuid)); } + +unsigned creation_mask(unsigned mask) { return static_cast(call(nr_umask, static_cast(mask))); } + } // namespace mcpplibs::os::kernel namespace mcpplibs::os::linux_kernel { diff --git a/src/linux/arch/x86_64.cpp b/src/linux/arch/x86_64.cpp index 0a03337..68c08e2 100644 --- a/src/linux/arch/x86_64.cpp +++ b/src/linux/arch/x86_64.cpp @@ -28,7 +28,8 @@ constexpr long nr_write = 1, nr_uname = 63, nr_sysinfo = 99, nr_statfs = 137, - nr_renameat2 = 316; + nr_renameat2 = 316, + nr_geteuid = 107, nr_umask = 95; constexpr long f_dupfd_cloexec = 1030, sig_unblock = 1; @@ -61,6 +62,10 @@ void raise_signal(int signal) { call(nr_kill, call(nr_getpid), signal); } +unsigned effective_user() { return static_cast(call(nr_geteuid)); } + +unsigned creation_mask(unsigned mask) { return static_cast(call(nr_umask, static_cast(mask))); } + } // namespace mcpplibs::os::kernel namespace mcpplibs::os::linux_kernel { diff --git a/src/macos/arch/aarch64.cpp b/src/macos/arch/aarch64.cpp index 22c9d27..c613d13 100644 --- a/src/macos/arch/aarch64.cpp +++ b/src/macos/arch/aarch64.cpp @@ -25,7 +25,8 @@ long call(long n, long a = 0, long b = 0, long c = 0, long d = 0, long e = 0) { } constexpr long nr_write = 4, nr_close = 6, nr_getpid = 20, nr_kill = 37, nr_sigaction = 46, - nr_sigprocmask = 48, nr_dup2 = 90, nr_fcntl = 92, nr_statfs64 = 345, nr_renameatx_np = 488; + nr_sigprocmask = 48, nr_dup2 = 90, nr_fcntl = 92, nr_statfs64 = 345, nr_renameatx_np = 488, + nr_geteuid = 25, nr_umask = 60; constexpr long f_dupfd_cloexec = 67, sig_unblock = 2; @@ -56,6 +57,10 @@ void raise_signal(int signal) { call(nr_kill, call(nr_getpid), signal, 1 /* POSIX */); } +unsigned effective_user() { return static_cast(call(nr_geteuid)); } + +unsigned creation_mask(unsigned mask) { return static_cast(call(nr_umask, static_cast(mask))); } + } // namespace mcpplibs::os::kernel namespace mcpplibs::os::macos_kernel { diff --git a/src/macos/arch/x86_64.cpp b/src/macos/arch/x86_64.cpp index eac1c95..7066384 100644 --- a/src/macos/arch/x86_64.cpp +++ b/src/macos/arch/x86_64.cpp @@ -22,7 +22,8 @@ long call(long n, long a = 0, long b = 0, long c = 0, long d = 0, long e = 0) { } constexpr long nr_write = 4, nr_close = 6, nr_getpid = 20, nr_kill = 37, nr_sigaction = 46, - nr_sigprocmask = 48, nr_dup2 = 90, nr_fcntl = 92, nr_statfs64 = 345, nr_renameatx_np = 488; + nr_sigprocmask = 48, nr_dup2 = 90, nr_fcntl = 92, nr_statfs64 = 345, nr_renameatx_np = 488, + nr_geteuid = 25, nr_umask = 60; constexpr long f_dupfd_cloexec = 67, sig_unblock = 2; @@ -53,6 +54,10 @@ void raise_signal(int signal) { call(nr_kill, call(nr_getpid), signal, 1 /* POSIX */); } +unsigned effective_user() { return static_cast(call(nr_geteuid)); } + +unsigned creation_mask(unsigned mask) { return static_cast(call(nr_umask, static_cast(mask))); } + } // namespace mcpplibs::os::kernel namespace mcpplibs::os::macos_kernel { diff --git a/src/posix/kernel.h b/src/posix/kernel.h index 2bb0859..2f511d2 100644 --- a/src/posix/kernel.h +++ b/src/posix/kernel.h @@ -1,4 +1,5 @@ -// The descriptors and the signals of the process, by the kernel's own calls: +// The descriptors, the signals, the user and the creation mask of the +// process, by the kernel's own calls: // what the units in src/posix/ do to the process rather than to the program's // C library. // @@ -27,6 +28,12 @@ long close(int fd); void default_signal(int signal); // The signal unblocked in this thread and sent to this process. void raise_signal(int signal); +// The process's effective user. A C library on openkal answers a constant +// here, for openkal names no user; the kernel names the one it checks. +unsigned effective_user(); +// The creation mask set to `mask'; the previous one is returned. The kernel +// applies it to every file the process creates, whatever library asks. +unsigned creation_mask(unsigned mask); inline constexpr int sigpipe = 13; // the same number on Linux and macOS diff --git a/src/posix/posix.cpp b/src/posix/posix.cpp index 7d3f800..5efbc65 100644 --- a/src/posix/posix.cpp +++ b/src/posix/posix.cpp @@ -1,6 +1,8 @@ +// mcpplibs.os.posix on Linux and macOS: the process's user and creation mask, +// asked of the kernel (src/posix/kernel.h) and not of the C library, which in +// the hosted arrangement sits on openkal and knows neither (0.4.0). module; -#include -#include +#include "kernel.h" module mcpplibs.os.posix; @@ -8,8 +10,8 @@ import std; namespace mcpplibs::os::posix { -std::uint32_t effective_user() { return static_cast(::geteuid()); } +std::uint32_t effective_user() { return kernel::effective_user(); } -void set_creation_mask(std::uint32_t mask) { ::umask(static_cast(mask)); } +void set_creation_mask(std::uint32_t mask) { kernel::creation_mask(mask); } } // namespace mcpplibs::os::posix diff --git a/tests/facts_test.cpp b/tests/facts_test.cpp index 5465355..8b62499 100644 --- a/tests/facts_test.cpp +++ b/tests/facts_test.cpp @@ -15,22 +15,30 @@ static_assert(!os::is_image || (os::can_run_on(os::platform::linux) && os::can_r && os::can_run_on(os::platform::windows)), "an image can run on every system a loader runs upon"); +// The effective user as the kernel names it, and as `id -u' does. A template, +// so that it is instantiated, and posix's name linked, only where `on

' +// calls it. +template +void check_effective_user(std::integral_constant, const char* system) { + const auto uid = os::posix::effective_user(); + auto id = os::process::run({.program = "/usr/bin/id", .args = {"-u"}, .err = os::process::stdio::null}); + const std::string named = id ? std::string(id->out.substr(0, id->out.find_first_of("\r\n"))) : "(id did not run)"; + std::printf(" note effective_user() = %u, id -u = %s\n", uid, named.c_str()); + check(std::to_string(uid) == named, std::format("{}: the effective user is the one `id -u' names", system).c_str()); +} + int main() { const bool ci = os::env::get("GITHUB_ACTIONS").has_value(); int asked = 0; - os::on([&](auto) { + os::on([&](auto p) { ++asked; check(!os::linux::translator().has_value() || !ci, "Linux: the runner is no translator"); - const auto uid = os::posix::effective_user(); - auto id = os::process::run({.program = "/usr/bin/id", .args = {"-u"}, .err = os::process::stdio::null}); - const std::string named = id ? std::string(id->out.substr(0, id->out.find_first_of("\r\n"))) : "(id did not run)"; - std::printf(" note effective_user() = %u, id -u = %s\n", uid, named.c_str()); - check(std::to_string(uid) == named, "Linux: the effective user is the one `id -u' names"); + check_effective_user(p, "Linux"); }); - os::on([&](auto) { + os::on([&](auto p) { ++asked; check(!os::macos::translated() || !os::is_image, "macOS: an image is never translated"); - check(os::posix::effective_user() != std::numeric_limits::max(), "macOS: the effective user is known"); + check_effective_user(p, "macOS"); }); os::on([&](auto) { ++asked; From dea950bfffec87cd2410fc4e85505af9e4422699 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Sun, 8 Nov 2026 04:24:15 +0900 Subject: [PATCH 4/5] platform: is_openkal, named as its platform is; is_image a deprecated alias Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ README.md | 4 ++-- checks/constants/src/main.cpp | 4 +++- src/platform.cppm | 10 ++++++++-- tests/facts_test.cpp | 6 +++--- tests/fs_test.cpp | 4 ++-- tests/platform_test.cpp | 8 ++++---- tests/process_test.cpp | 8 ++++---- 8 files changed, 33 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f452440..8d2ee74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## 0.4.0 +- **`is_openkal`, named as its platform is.** A build for the openkal target + (`-openkal`, mcpp's `cfg(os = "openkal")`), whose artifact is an ok + image, is `is_openkal`, as a build for Linux is `is_linux`: each + `is_` names the target of the build, and `platform::openkal` is + this one's. `is_image`, its name since 0.1.0, read as though it named a + container's or a disk's image, and as though only it were over openkal, which + every build of this package is. It remains, deprecated, as the same constant. - **A platform question for a native build and an image alike.** `can_run_on(p)` says whether this build can run on `p` (a native build on its own system, an image on every system a loader runs upon), and `on

(f)` runs `f` when the diff --git a/README.md b/README.md index 87e48ef..44050a0 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ dropped (0.2.8). | Module | Contents | |---|---| -| `mcpplibs.os.platform` | `PLATFORM`, `ARCH`, `is_linux` / `is_macos` / `is_windows` / `is_posix` / `is_emscripten`, `exe_suffix`, `path_list_separator`; `host()`, a constant expression on a native target; `can_run_on(p)` and `on

(f)`, a platform question that holds in a native build and an image alike | +| `mcpplibs.os.platform` | `PLATFORM`, `ARCH`, `is_linux` / `is_macos` / `is_windows` / `is_posix` / `is_openkal` / `is_emscripten`, `exe_suffix`, `path_list_separator`; `host()`, a constant expression on a native target; `can_run_on(p)` and `on

(f)`, a platform question that holds in a native build and an image alike | | `mcpplibs.os.error` | `errc` (openkal's closed set of conditions), `error`, `result` | | `mcpplibs.os.env` | variables (names without case on Windows), `NAME=value` entries as overrides (`assignments`), arguments, the program's own image, lists of directories in the host's separator (`split_list`, `join_list`), PATH search with PATHEXT | | `mcpplibs.os.fs` | `write_atomic`, `publish` (no replace), `append`, `sync`, `caps`, `lock`, links, `set_executable`, `stamp_of`, `identity_of`, `owner_of`, `writable`, `locate`, `absolute`, `names_a_place`, `canonical`, a bounded `read`; what a volume does, measured (`measure`, `volume_type`), and the operations that follow it (`place`, `exchange`); names in the host's rules without the file system: `generic`, `native`, `extended`, `is_absolute`, `same`, `within` | @@ -195,7 +195,7 @@ openkal's capability and is answered by the start itself (openkal SPEC clause 30 Built for `-openkal` (openkal SPEC clause 12), a program over this library is one image per architecture that `okrun` runs on Linux, macOS and Windows. -`os::PLATFORM` is `platform::openkal` and `os::is_image` is true; `os::host()` +`os::PLATFORM` is `platform::openkal` and `os::is_openkal` is true; `os::host()` is an ordinary function there, answered when the image is loaded, and `os::conventions()` follows it; `exe_suffix` and `path_list_separator` are not provided, so code that reads them is a compile error rather than a wrong answer diff --git a/checks/constants/src/main.cpp b/checks/constants/src/main.cpp index 402b556..921aee1 100644 --- a/checks/constants/src/main.cpp +++ b/checks/constants/src/main.cpp @@ -7,7 +7,9 @@ namespace os = mcpplibs::os; static_assert(os::host() == os::PLATFORM); static_assert(os::is_linux + os::is_macos + os::is_windows + os::is_emscripten == 1); -static_assert(!os::is_image); +static_assert(!os::is_openkal); +// 0.1.0-0.3.x's name, kept as a deprecated alias of the same constant (0.4.0): it compiles, warning. +static_assert(os::is_image == os::is_openkal); static_assert(os::exe_suffix == (os::is_windows ? ".exe" : "")); static_assert(os::path_list_separator == (os::is_windows ? ';' : ':')); static_assert(os::conventions_of(os::host()).exe_suffix == os::exe_suffix); diff --git a/src/platform.cppm b/src/platform.cppm index 73765fb..f0c28b9 100644 --- a/src/platform.cppm +++ b/src/platform.cppm @@ -26,7 +26,13 @@ inline constexpr bool is_linux = PLATFORM == platform::linux; inline constexpr bool is_macos = PLATFORM == platform::macos; inline constexpr bool is_windows = PLATFORM == platform::windows; inline constexpr bool is_posix = is_linux || is_macos; -inline constexpr bool is_image = PLATFORM == platform::openkal; +// A build for the openkal target, `-openkal` (mcpp `cfg(os = "openkal")`): its artifact is an +// ok image (openkal SPEC clause 12), which a loader runs on every system. It does not say that the +// build is over openkal -- every build of this package is -- but which target it is built for, as +// each `is_` does (0.4.0; `is_image` before). +inline constexpr bool is_openkal = PLATFORM == platform::openkal; +[[deprecated("use is_openkal: a build for the openkal target, whose artifact is an ok image")]] +inline constexpr bool is_image = is_openkal; // A wasm module over Emscripten's C library (0.2.2): no program is started and // no library loaded, the file system is the module's own (MEMFS), and the // streams are the host's. @@ -47,7 +53,7 @@ inline constexpr bool is_emscripten = PLATFORM == platform::emscripten; // build (a discarded statement is no odr-use, R5); the second is what an image // decides by. constexpr bool can_run_on(platform p) noexcept { - if constexpr (is_image) return p == platform::linux || p == platform::macos || p == platform::windows; + if constexpr (is_openkal) return p == platform::linux || p == platform::macos || p == platform::windows; else return PLATFORM == p; } diff --git a/tests/facts_test.cpp b/tests/facts_test.cpp index 8b62499..97ec193 100644 --- a/tests/facts_test.cpp +++ b/tests/facts_test.cpp @@ -8,10 +8,10 @@ import mcpplibs.os; namespace os = mcpplibs::os; -static_assert(os::can_run_on(os::PLATFORM) || os::is_image, "a native build runs on its own system"); +static_assert(os::can_run_on(os::PLATFORM) || os::is_openkal, "a native build runs on its own system"); static_assert(!os::can_run_on(os::platform::openkal), "an image is a target, never a system it runs upon"); static_assert(!os::can_run_on(os::platform::emscripten) || os::is_emscripten, "no image runs under Emscripten"); -static_assert(!os::is_image || (os::can_run_on(os::platform::linux) && os::can_run_on(os::platform::macos) +static_assert(!os::is_openkal || (os::can_run_on(os::platform::linux) && os::can_run_on(os::platform::macos) && os::can_run_on(os::platform::windows)), "an image can run on every system a loader runs upon"); @@ -37,7 +37,7 @@ int main() { }); os::on([&](auto p) { ++asked; - check(!os::macos::translated() || !os::is_image, "macOS: an image is never translated"); + check(!os::macos::translated() || !os::is_openkal, "macOS: an image is never translated"); check_effective_user(p, "macOS"); }); os::on([&](auto) { diff --git a/tests/fs_test.cpp b/tests/fs_test.cpp index 8441e71..d7702da 100644 --- a/tests/fs_test.cpp +++ b/tests/fs_test.cpp @@ -175,7 +175,7 @@ int main() { const auto b = os::fs::measure(dir); check(b.measured, "a writable directory's volume is measured"); // The kind of a volume is the system's to name; an image is not told it. - if constexpr (!os::is_image) + if constexpr (!os::is_openkal) check(!b.type.empty() && b.type != "0x0", "and its kind is named by the system"); (void)os::fs::write(dir / "x", "x"); check(os::fs::place(dir / "x", dir / "y").has_value() && os::fs::read(dir / "y").value_or("") == "x" @@ -189,7 +189,7 @@ int main() { check(os::fs::exchange(dir / "p", dir / "q").has_value() && os::fs::read(dir / "p").value_or("") == "q" && os::fs::read(dir / "q").value_or("") == "p", "two entries trade places"); - if (!os::is_image) { + if (!os::is_openkal) { check(os::fs::owner_of(dir) == os::fs::owner::this_user, "a directory this program made is its user's"); check(os::fs::writable(dir), "and this user may write it"); } diff --git a/tests/platform_test.cpp b/tests/platform_test.cpp index 8739e5c..7cfc429 100644 --- a/tests/platform_test.cpp +++ b/tests/platform_test.cpp @@ -8,7 +8,7 @@ import mcpplibs.os; namespace os = mcpplibs::os; -static_assert(os::is_linux + os::is_macos + os::is_windows + os::is_image + os::is_emscripten == 1); +static_assert(os::is_linux + os::is_macos + os::is_windows + os::is_openkal + os::is_emscripten == 1); static_assert(os::is_posix == (os::is_linux || os::is_macos)); static_assert(os::name(os::ARCH) == "x86_64" || os::name(os::ARCH) == "aarch64" || os::name(os::ARCH) == "riscv64" || os::name(os::ARCH) == "wasm32"); @@ -17,7 +17,7 @@ static_assert(os::is_emscripten == (os::name(os::ARCH) == "wasm32")); int main() { const auto host = os::host(); check(host != os::platform::openkal, "the host is a system, whatever the target"); - if constexpr (!os::is_image) check(host == os::PLATFORM, "built for a system, the host is that system"); + if constexpr (!os::is_openkal) check(host == os::PLATFORM, "built for a system, the host is that system"); else check(os::env::loader().has_value(), "an image is told the program that runs it"); check(os::conventions().exe_suffix == (host == os::platform::windows ? ".exe" : ""), "the host's conventions are the host's"); @@ -35,14 +35,14 @@ int main() { check(os::machine::arch() == "wasm32", "Emscripten: the machine is the module's"); check(!os::machine::memory() && !os::machine::memory_available(), "Emscripten: the machine's memory is not known"); } - if constexpr (!os::is_image && !os::is_emscripten) + if constexpr (!os::is_openkal && !os::is_emscripten) check(os::machine::memory().value_or(0) > 0, "the machine's memory is known"); const auto a = os::random::hex(16), b = os::random::hex(16); check(a && a->size() == 32 && b && *a != *b, "the system's source gives bytes that differ from call to call"); { const auto p = os::machine::processors(); check(p.logical >= 1 && p.physical >= 1 && p.physical <= p.logical, "processors: logical and physical counted"); - if (!os::is_image && !os::is_emscripten) + if (!os::is_openkal && !os::is_emscripten) check(os::machine::memory_available().value_or(0) > 0, "and the memory available now"); } if constexpr (os::is_windows) { diff --git a/tests/process_test.cpp b/tests/process_test.cpp index e200711..e5725d7 100644 --- a/tests/process_test.cpp +++ b/tests/process_test.cpp @@ -243,7 +243,7 @@ int main(int argc, char** argv) { auto r = os::process::run(o, limits); check(r && r->status.success() && r->held_open, "a bounded run says an output was held open, and ends the unit"); } - if (os::host() == os::platform::linux && !os::is_image) { + if (os::host() == os::platform::linux && !os::is_openkal) { // 0.2.1: the threads of a running program, each with its time. const auto me = os::process::self(); const auto threads = me ? os::process::threads(me->id) : std::vector{}; @@ -364,7 +364,7 @@ int main(int argc, char** argv) { check(!r && r.error().code == os::errc::not_program, "a file that is no image is not a program to become"); std::filesystem::remove(file); } - if (!os::is_image) { + if (!os::is_openkal) { auto o = copy("wait-input"); o.in = os::process::stdio::pipe; o.out = os::process::stdio::pipe; @@ -408,7 +408,7 @@ int main(int argc, char** argv) { "a joined command line is refused where a program receives a vector"); } } - if (!os::is_image) { + if (!os::is_openkal) { auto r = os::process::run(copy("end-closed")); if (os::host() == os::platform::windows) check(r && r->status.code == 5, "Windows has no ending for a closed reader, and the program goes on"); @@ -422,7 +422,7 @@ int main(int argc, char** argv) { check(me && os::process::alive(*me), "and is alive"); } // The program the system starts: this one, or in an ok image its loader. - const auto started = os::is_image ? os::env::loader() : self; + const auto started = os::is_openkal ? os::env::loader() : self; if (started) { const auto whole = os::fs::absolute(*started); check(os::env::find_executable(whole.filename().string(), whole.parent_path().string()).has_value(), From 94d6b83d3b9ba7c239659c9fc01398c06d5df2c6 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Sun, 8 Nov 2026 06:30:08 +0900 Subject: [PATCH 5/5] ci: openkal-platform 0.24.4 with mcpp 2026.11.7.2, which resolves within the platform's version group Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com> --- .github/workflows/ci.yml | 20 ++++++++++++-------- .github/workflows/unit-lifecycle.yml | 2 +- checks/hosted/mcpp.toml | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e421dad..54bff43 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,9 @@ name: CI # run under node (checks/emscripten); a program that starts one # fails at LINK naming the openkal symbol (checks/absent) # -# The library is built with the released mcpp, 2026.11.5.1. The ok images +# The library is built with the released mcpp, 2026.11.7.2, which resolves +# within the platform's version group (an earlier mcpp takes the newest member +# of a range and then refuses it against the group). The ok images # (MCPP_PLATFORM) and checks/hosted select openkal-platform 0.24 and its # OpenKal 0.24 implementation, musl 0.28 and C++ runtime 0.19 group. The library # itself needs 2026.10.27.1 or later, the first that selects a platform @@ -35,7 +37,7 @@ env: MCPP_SOURCE_REF: ${{ github.event.inputs.mcpp_ref || vars.MCPP_SOURCE_REF || '' }} # 2026.11.3.1: the std module compiled with the platform's words (openkal-platform 0.23.0's # `-fcf-protection=full` refused every `import std` of an earlier mcpp's). - MCPP_INSTALL: ${{ (github.event.inputs.mcpp_ref || vars.MCPP_SOURCE_REF) && 'mcpp' || 'mcpp@2026.11.5.1' }} + MCPP_INSTALL: ${{ (github.event.inputs.mcpp_ref || vars.MCPP_SOURCE_REF) && 'mcpp' || 'mcpp@2026.11.7.2' }} XLINGS_VERSION: v2026.10.26.1 XLINGS_NON_INTERACTIVE: '1' @@ -225,11 +227,12 @@ jobs: timeout-minutes: 120 env: # openkal 0.24.0, which this release is written against, in the group of - # openkal-platform 0.24.3: its C++ run-time keeps the volume of a + # openkal-platform 0.24.4: its C++ run-time keeps the volume of a # normalized name (openkal-llvm-runtime 0.19.2, which the long-spelling # tests of 0.3.1 need on Windows), and its tools are openkal-ld and - # openkal-run 0.5.2, which the graph resolves since they were published. - MCPP_PLATFORM: openkal-platform@0.24.3 + # openkal-run 0.5.3, whose okrun enters an image in its convention's + # floating-point state. + MCPP_PLATFORM: openkal-platform@0.24.4 defaults: run: shell: bash @@ -279,11 +282,12 @@ jobs: timeout-minutes: 45 env: # openkal 0.24.0, which this release is written against, in the group of - # openkal-platform 0.24.3: its C++ run-time keeps the volume of a + # openkal-platform 0.24.4: its C++ run-time keeps the volume of a # normalized name (openkal-llvm-runtime 0.19.2, which the long-spelling # tests of 0.3.1 need on Windows), and its tools are openkal-ld and - # openkal-run 0.5.2, which the graph resolves since they were published. - MCPP_PLATFORM: openkal-platform@0.24.3 + # openkal-run 0.5.3, whose okrun enters an image in its convention's + # floating-point state. + MCPP_PLATFORM: openkal-platform@0.24.4 strategy: fail-fast: false matrix: diff --git a/.github/workflows/unit-lifecycle.yml b/.github/workflows/unit-lifecycle.yml index f78bb66..8107a01 100644 --- a/.github/workflows/unit-lifecycle.yml +++ b/.github/workflows/unit-lifecycle.yml @@ -52,7 +52,7 @@ jobs: - name: Install the actual native compiler run: | xlings update - xlings install mcpp@2026.11.5.1 -y -g + xlings install mcpp@2026.11.7.2 -y -g spec='${{ matrix.toolchain }}' case "$spec" in msvc@system) mcpp toolchain default msvc ;; diff --git a/checks/hosted/mcpp.toml b/checks/hosted/mcpp.toml index 655bb2a..09bb451 100644 --- a/checks/hosted/mcpp.toml +++ b/checks/hosted/mcpp.toml @@ -13,7 +13,7 @@ version = "0.1.0" os = { path = "../.." } [target.'cfg(any(linux, macos, windows))'] -platform = "openkal-platform@0.24.3" +platform = "openkal-platform@0.24.4" # The tests are the package's own, each reached by an include from # tests/.cpp here (a test program is a file of the package that runs it).