Skip to content

fix: Stop assuming POSIX paths and permissions on a host without them - #3

Open
Yos-X wants to merge 4 commits into
masterfrom
fix/platform
Open

Yos-X wants to merge 4 commits into
masterfrom
fix/platform

Conversation

@Yos-X

@Yos-X Yos-X commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

Four places in three modules assume a POSIX host. On Windows two of them keep the runtime from working at all, and two fail tests of this repository. Each is a commit of its own.

standardRoots denies Path.of("/dev") on every host, and a host without a device tree reads that path as \dev, which names no root of its own. Canonicalizing it is refused:

java.lang.IllegalArgumentException: A path to canonicalize is absolute and of the default file system, was '\dev'.

AgentFloor is built from those roots, so the agent plugin is not created at all, and everything that starts the runtime fails before a test runs:

Cannot start runtime 'harness': stage GRAPH failed (1 problem):
- Cannot create org.foedusprogramme.alexandrite.agent.permission.AgentFloor with
  org.foedusprogramme.alexandrite.agent.permission.AgentFloor (plugin alexandrite-agent):
  java.lang.IllegalArgumentException: A path to canonicalize is absolute and of the default file system, was '\dev'.

265 of the 658 tests of :libraries:agent:test fail that way in this checkout, and the message names the floor rather than the platform. The device tree is denied where the host separates paths with /, and nowhere else.

writeAtomically makes its temporary file with a POSIX permissions attribute, which such a host refuses:

java.lang.UnsupportedOperationException: 'posix:permissions' not supported as initial attribute

The attribute view is absent there, and targetPermissions reads that absence as no permissions to take and falls back to owner-only, so the attribute is passed and making the file throws. fs.write, fs.edit and the persona tools then fail whatever they write. The permissions are read where the host keeps them, and the attribute is passed only then: a file that is replaced still takes the permissions of the one it replaced, and the write stays atomic.

The tests of app and build-ksp-plugin assert POSIX spellings, POSIX line endings, the wording a POSIX host gives for a path it refuses, and the text of one host's separator. Each assertion is taken from the host under test: Path.of, the host's line endings, the reason that host gives, and a comparison of paths as paths.

The four commits were checked on Windows. :libraries:internal:test --tests '*AtomicWrites*' passes 6 tests, where 1 failed without the write fix. :libraries:agent:test loses the 265 failures that could not start the runtime, and they return when the device-tree commit is left out. :app:test --tests '*LocationsTest*' --tests '*MainTest*' goes from 9 failures to 1, which is a control socket that a host without sockets keeps none of. :build-ksp-plugin:test passes 115 tests, where 2 failed. spotlessCheck passes for each module touched.

macOS was not run, and the assertions speak of it as well. The Linux run of CI passes these four places already, so nothing changes there.

Yos-X added 4 commits October 13, 2026 18:41
writeAtomically makes its temporary file with a POSIX permissions attribute. A host that keeps no permissions of that kind refuses the attribute and makes no file at all, so every write fails on such a host: the attribute view is absent there, which targetPermissions reads as no permissions to take.

The permissions are read where the host keeps them now, and the attribute is passed only then. A file that is replaced still takes the permissions of the one it replaces, and the write is still atomic.
The floor denies /dev on every host. On a host without a device tree that path is \dev, which names no root of its own, so no check can canonicalize it and the floor cannot be built: AgentFloor is made of those roots, so the agent plugin is not created at all and everything that starts the runtime fails on such a host.

The device tree is a root where there is one, so it is denied where the host separates paths with a slash and nowhere else.
Seven tests of this module passed on Linux and failed on Windows, and none of
them was about the code under test. Each one wrote an expectation in the
syntax of one platform while the value comes from the host:

- The XDG cases fed the variables /xdg/data, which Windows does not call an
  absolute path, so the code fell back to its own directories. They now name
  directories in the syntax of the host that resolves them, which is what the
  case is about: the precedence of the variables, not the separator.
- The cases that compare whole paths run against the systems whose syntax the
  host shares. A POSIX path is not rendered the same way on Windows, and no
  assertion can change that.
- A refused path reports a wording each host has its own for, and Windows
  names the offending character itself: Illegal char <NUL>., with a real
  null between the brackets. The expected reason is read from the host now
  instead of being written out.
- --help, --version and the usage on a bad argument are compared after
  their line endings are made the same, because the host prints \r\n.
- The named data directory of the --help case was written with doubled
  backslashes, which the program never prints.

The formatting of the KSP assertions from the commit before this one came
along, since spotlessCheck wants the call that did not fit on a line
broken up.

Verified: :app:test passes, 45 tests, and :build-ksp-plugin:test passes, 118
tests, both on Windows, with their spotlessCheck; the assertions the two
commits touch were passing on Linux before and are unchanged in what they
check there.
Two tests wrote the data directory into the expected report as a slash
separated string while the code renders it with Path.toString, so they
passed on Linux and failed on Windows, where the same path prints with
backslashes. They now build the expectation from the same Path the probe
holds, which is what the assertion is about; the separator stops mattering.

Verified: :build-ksp-plugin:test passes, 118 tests, on Windows. The suite
also passes on Linux, where the old expectation happened to be right.
@Yos-X Yos-X changed the title platform: Fix what assumes POSIX paths and permissions on a host without them fix: Stop assuming POSIX paths and permissions on a host without them Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant