Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,15 @@ jobs:
| grep -q "argc as kal_env_arg_count = 2") \
|| { echo "::error::a relative image name with .. was not opened"; exit 1; }
echo " ok a relative name that climbs opens the image"
# A NAME WITH EMPTY COMPONENTS (0.6.4): `//' and `/./' in an absolute
# name, as a build system's joined paths carry them, fold lexically.
abs="$PWD"; [ "$RUNNER_OS" = Windows ] && abs=$(cygpath -m "$PWD")
"$OKRUN" "$abs//out/./$a//hello.oke" one | tr -d '\r' | grep -q "argc as kal_env_arg_count = 2" \
|| { echo "::error::an absolute image name with // was not opened"; exit 1; }
(cd rel/below && "$OKRUN" "..//..//out/$a/hello.oke" one | tr -d '\r' \
| grep -q "argc as kal_env_arg_count = 2") \
|| { echo "::error::a relative image name with // was not opened"; exit 1; }
echo " ok a name with empty components opens the image"
n=$("$OKRUN" "out/$a/needed.oke" | tr -d '\r')
echo "$n"
grep -q "twice(21) = 42, next_value() = 41" <<<"$n" || { echo "::error::an image another needs"; exit 1; }
Expand Down
46 changes: 42 additions & 4 deletions .github/workflows/release-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ name: release binaries

# okrun and okld as programs of each system and architecture, attached to a
# release: what a machine without mcpp installs to run ok images (the
# xim-pkgindex `okrun` package). Dispatched with the release's tag; each archive
# xim-pkgindex `okrun` package). A published release starts it (0.6.4: 0.6.3 was
# published without binaries because the dispatch was a separate step); a
# dispatch with a tag rebuilds an earlier release under a new asset revision. Each archive
# is `mcpp pack` of the tool, a static program on Linux, and carries its
# mcpp-package.json, from which `mcpp emit xpkg --package` writes the index
# entry.

on:
release:
types: [published]
workflow_dispatch:
inputs:
tag:
Expand All @@ -30,18 +34,22 @@ permissions:
contents: write

env:
RELEASE_TAG: ${{ github.event.inputs.tag }}
RELEASE_TAG: ${{ github.event.inputs.tag || github.event.release.tag_name }}
ASSET_REVISION: ${{ github.event.inputs.asset_revision || '' }}
MCPP_SOURCE_REF: ${{ github.event.inputs.mcpp_ref || vars.MCPP_SOURCE_REF || '' }}
# 2026.11.10.1: openkal-run binds the interfaces its implementation provides.
# mcpp_ref supplies the candidate until this release is installable.
MCPP_VERSION: 2026.11.13.1
# 2026.11.15.1: openkal-platform 0.28.0, the default platform below, requires
# 2026.11.14.1 or later.
MCPP_VERSION: 2026.11.15.1
# The platform whose hosted arrangement the programs are built over, named by
# the dispatch beside the tag: a tag's tools pin exact implementations, and the
# platform is the one whose version group holds them (0.1.4: 0.18.0; 0.1.5:
# 0.19.0, openkal-linux 0.19.0; 0.1.6: 0.19.1; 0.1.7: 0.19.2; 0.1.8: 0.20.0; 0.1.9: 0.20.1;
# 0.3.0: 0.21.0; 0.3.1: 0.21.1; 0.4.2: 0.23.1; 0.4.3 and 0.4.4: 0.23.3).
PLATFORM_VERSION: ${{ github.event.inputs.platform }}
# A published release builds over the platform named here, which a release
# that changes the pinned implementations updates in the same commit.
PLATFORM_VERSION: ${{ github.event.inputs.platform || '0.28.0' }}
XLINGS_VERSION: v2026.10.26.1
XLINGS_NON_INTERACTIVE: '1'

Expand All @@ -63,6 +71,12 @@ jobs:
- { os: ubuntu-24.04-arm, id: linux-aarch64, pack: '--target aarch64-linux-musl --mode static' }
- { os: macos-15, id: macos-aarch64, pack: '--target aarch64-macos' }
- { os: windows-2022, id: windows-x86_64, pack: '--target x86_64-windows-gnu' }
# FreeBSD (0.6.4): the musl identity of the platform's hosted
# arrangement, built on Linux (the runner's `built-as`), one static
# program, and run in a FreeBSD machine before it is attached. These
# are the programs a runner delivers into a FreeBSD guest.
- { os: ubuntu-24.04, id: freebsd-x86_64, pack: '--target x86_64-freebsd-musl --mode static', vm: x86_64 }
- { os: ubuntu-24.04, id: freebsd-aarch64, pack: '--target aarch64-freebsd-musl --mode static', vm: aarch64 }
defaults:
run:
shell: bash
Expand Down Expand Up @@ -152,6 +166,7 @@ jobs:
ls -l ../out

- name: Each program runs here, from its package alone
if: ${{ !matrix.vm }}
run: |
python=python3; [ "$RUNNER_OS" = Windows ] && python=python
tag="$RELEASE_TAG"
Expand Down Expand Up @@ -182,6 +197,29 @@ jobs:
grep -q "usage: $tool" "$tool.out" || { echo "::error::$tool did not run here"; exit 1; }
done

- name: Unpacked for the FreeBSD machine
if: ${{ matrix.vm }}
run: |
mkdir -p vm
for tool in okrun okld okprof; do
unzip -q -o "out/$tool-$RELEASE_TAG$ASSET_SUFFIX-${{ matrix.id }}.zip" -d vm
done
ls vm
- name: Each program runs in FreeBSD, from its package alone
if: ${{ matrix.vm }}
uses: vmactions/freebsd-vm@v1
with:
arch: ${{ matrix.vm }}
usesh: true
run: |
uname -a
for pkg in vm/*/; do
tool=$(basename "$pkg" | cut -d- -f1)
"$pkg/$tool" > "$tool.out" 2>&1 || true
cat "$tool.out"
grep -q "usage: $tool" "$tool.out" || { echo "$tool did not run here"; exit 1; }
done

- name: Debug the just-unpacked Linux runner
if: matrix.id == 'linux-x86_64'
run: |
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ of the row `i686-openkal`, built through openkal-platform 0.28.0 (C++23 with
`i686-linux-musl` on an x86-64 Linux, and gdb stops at a line of it and unwinds
into the runner, as for an x86-64 image (measured).

Version 0.6.4 folds every image name lexically before it is matched, an
absolute one as well as a relative one: an empty component (`//`, as a build
system's joined paths carry it) and `.` are dropped, and `..` removes the
component before it. An absolute name was matched as it stood, so `/a//b.oke`
was refused. The release workflow starts when a release is published, so every
release carries its binaries (0.6.3 was published without them), and it adds
FreeBSD x86_64 and aarch64: static programs of the platform's hosted musl
identity, built on Linux and run in a FreeBSD machine before they are attached.

## An image

```sh
Expand Down
2 changes: 1 addition & 1 deletion bind/mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
namespace = "mcpplibs"
name = "openkal-bind"
version = "0.6.2"
version = "0.6.4"
# `mcpp::xpkg_request', `mcpp::decision' (protocol 15).
mcpp = ">=2026.10.1.3"
description = "A build plugin: a library published as an ok image (.okso) and a C header is called from a program of any system, through a binding generated from the header and libokrun."
Expand Down
2 changes: 1 addition & 1 deletion ld/mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
namespace = "mcpplibs"
name = "openkal-ld"
version = "0.6.3"
version = "0.6.4"
description = "libokld: the ok format (openkal image format) --- its definition, a reader of bytes, a checker, a signer, and a loader. Freestanding: no C library, no exceptions."
license = "Apache-2.0"
authors = ["mcpplibs"]
Expand Down
2 changes: 1 addition & 1 deletion run/mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
namespace = "mcpplibs"
name = "openkal-run"
version = "0.6.3"
version = "0.6.4"
description = "libokrun: the runner's core --- an ok image's names bound to this process's one openkal implementation, in the image's calling convention, and its entry entered."
license = "Apache-2.0"
authors = ["mcpplibs"]
Expand Down
88 changes: 56 additions & 32 deletions run/src/full/run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,47 +68,71 @@ void* allocate(okld_size n, void*) { return kal_alloc(n, 16); }
void deallocate(void* p, okld_size n, void*) { kal_free(p, n, 16); }

// A name as openkal names things: the supplied directory that is the longest
// prefix of it, and the rest. A relative name is folded against the first
// directory's name --- `..' and `.' lexically, a symlink not resolved --- into
// the absolute one beneath it and matched as that. It folds into `g_folded',
// which outlives the call: the rest points into it.
// prefix of it, and the rest. Every name is folded lexically before it is
// matched --- empty components (`//'), `.' and `..' --- and a symlink is not
// resolved. A relative name is first placed beneath the first directory's name.
// It folds into `g_folded', which outlives the call: the rest points into it.
bool separator(char c) { return c == '/' || c == '\\'; }
char lower(char c) { return (c >= 'A' && c <= 'Z') ? static_cast<char>(c - 'A' + 'a') : c; }

char g_folded[1024];

bool locate(const char* path, kal_dir& dir, const char*& rest) {
const char* name = path;
if (!(separator(path[0]) || (path[0] && path[1] == ':'))) {
// The root of an absolute name: `/', or a drive's `X:/'. Zero: not absolute.
unsigned long root_length(const char* p) {
if (separator(p[0])) return 1;
if (p[0] && p[1] == ':' && separator(p[2])) return 3;
return 0;
}

bool fold(const char* path) {
unsigned long at = 0, floor = 0;
const char* rest = path;
if (const unsigned long r = root_length(path)) {
for (unsigned long i = 0; i < r; ++i) g_folded[at++] = separator(path[i]) ? '/' : path[i];
rest = path + r;
floor = r;
} else {
kal_dir first{};
char base[1024]; kal_uintptr blen = 0;
if (kal_fs_preopen(0, &dir, base, sizeof base, &blen) != kal_ok
if (kal_fs_preopen(0, &first, base, sizeof base, &blen) != kal_ok
|| blen == 0 || blen >= sizeof g_folded) return false;
unsigned long at = 0;
while (at < blen) { g_folded[at] = base[at]; ++at; }
if (!separator(g_folded[at - 1])) g_folded[at++] = '/';
// `..' may climb out of the first directory, to the root of what it
// then names: the whole tree, or a drive's. No higher.
unsigned long floor = at;
if (blen > 1 && separator(g_folded[0])) floor = 1;
else if (blen > 3 && g_folded[1] == ':' && separator(g_folded[2])) floor = 3;
for (const char* p = path; *p;) {
const char* s = p;
while (*p && !separator(*p)) ++p;
const unsigned long n = static_cast<unsigned long>(p - s);
while (separator(*p)) ++p;
if (n == 0 || (n == 1 && s[0] == '.')) continue;
if (n == 2 && s[0] == '.' && s[1] == '.') {
if (at <= floor) return false;
do --at; while (at > floor && !separator(g_folded[at - 1]));
continue;
}
if (at && !separator(g_folded[at - 1])) g_folded[at++] = '/';
if (at + n >= sizeof g_folded) return false;
for (unsigned long i = 0; i < n; ++i) g_folded[at++] = s[i];
base[blen] = 0;
if (root_length(base)) {
// The first directory's own name is folded too, then the relative
// name beneath it; `..' may climb to the root of what it names.
if (!fold(base)) return false;
while (g_folded[at]) ++at;
floor = root_length(g_folded);
} else {
// A first directory with no root: `..' may not climb out of it.
while (at < blen) { g_folded[at] = base[at]; ++at; }
if (!separator(g_folded[at - 1])) g_folded[at++] = '/';
floor = at;
}
g_folded[at] = 0;
name = g_folded;
}
for (const char* p = rest; *p;) {
const char* s = p;
while (*p && !separator(*p)) ++p;
const unsigned long n = static_cast<unsigned long>(p - s);
while (separator(*p)) ++p;
if (n == 0 || (n == 1 && s[0] == '.')) continue;
if (n == 2 && s[0] == '.' && s[1] == '.') {
if (at <= floor) return false;
do --at; while (at > floor && !separator(g_folded[at - 1]));
continue;
}
if (at > floor && !separator(g_folded[at - 1])) g_folded[at++] = '/';
if (at + n + 1 >= sizeof g_folded) return false;
for (unsigned long i = 0; i < n; ++i) g_folded[at++] = s[i];
}
if (at > floor && separator(g_folded[at - 1])) --at;
g_folded[at] = 0;
return true;
}

bool locate(const char* path, kal_dir& dir, const char*& rest) {
if (!fold(path)) return false;
const char* name = g_folded;
unsigned long best = 0;
bool found = false;
for (kal_uintptr i = 0; i < kal_fs_preopen_count(); ++i) {
Expand Down
2 changes: 1 addition & 1 deletion tools/mcpp.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
namespace = "mcpplibs"
name = "openkal-tools"
version = "0.6.3"
version = "0.6.4"
description = "okrun, which runs an ok image on this system, and okld, the format's tool on a build machine (check, note, sign, inspect)."
license = "Apache-2.0"
authors = ["mcpplibs"]
Expand Down
Loading