Skip to content

Initial port for AIX - #109

Closed
mehendarkarprajwal wants to merge 1 commit into
sheredom:mainfrom
mehendarkarprajwal:main
Closed

Initial port for AIX#109
mehendarkarprajwal wants to merge 1 commit into
sheredom:mainfrom
mehendarkarprajwal:main

Conversation

@mehendarkarprajwal

Copy link
Copy Markdown
Contributor

Recently llama.cpp started using upstream subprocess.h for launching llama-server in router mode.
Here -> ggml-org/llama.cpp@ec18edf
And some of the APIs used in this file are not present on AIX natively. So using combination of other primitive APIs like fork() and exec() I have replicated the functionality of the posix_spawn_file_actions_addchdir
With these changes llama.cpp now works smoothly on AIX.

Please let me know if any changes required
thank you!!

@sheredom

sheredom commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Is there anyway to test for AIX? Does #104 not 'solve' the cwd issue?

@bernardladenthin

bernardladenthin commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Before I get to AIX: this currently doesn't build on the non-AIX path with the project's
own warning settings.

subprocess.h:1137: error: unused variable 'actions_created' [-Werror=unused-variable]
subprocess.h:1138: error: unused variable 'posix_error'
subprocess.h:1139: error: unused variable 'actions'

They are still declared at function scope in the #else branch, but the posix_spawn code
now redeclares them in the new inner scope, and the if (actions_created) cleanup is gone.
Dropping the outer three should be enough.

The AIX path itself looks sound. Forcing -D_AIX on Linux builds and passes the full
suite, 432/432 — chdir takes effect in the child and a missing binary reports
subprocess_error_not_found. (Rebased onto main you also need #104's SUBPROCESS_HAVE_CWD,
otherwise the 9 cwd tests are silently skipped.)

That is also a cheap answer to the CI question: the AIX branch can be compiled and
exercised on any Linux runner via -D_AIX, which would have caught the build error above.

One thing to expect on real AIX, unrelated to this PR: create_subprocess_fail_divzero
will fail in all 9 language modes. PowerPC does not trap on integer division by zero, so
the child never dies from SIGFPE. Measured on ppc64le Linux — x86 exits 136, POWER returns
a value and exits 0. Worth guarding the test by architecture rather than debugging it.

I'm trying to get access to an AIX machine to confirm the AIX-specific parts (execvpe,
posix_spawn behaviour) and will report back.

@bernardladenthin

Copy link
Copy Markdown
Contributor

Follow-up: I now have AIX 7.2 TL04 (7200-04-02-2027) running on POWER8 with
GCC 13.3.0, so the AIX-specific parts are confirmed on a real system rather than
by forcing -D_AIX on Linux.

Both premises of this PR hold. posix_spawn_file_actions_addchdir_np is
absent from spawn.h and from libc.a, and execvpe is exported but declared
in no header — the comment in the diff is accurate word for word.

@sheredom, to your two questions:

Does #104 solve the cwd issue? No. #104 made the probe correct for old glibc
and old macOS, but AIX defines neither __GLIBC__ nor __APPLE__, so it falls
through to the #else and is told SUBPROCESS_HAVE_CWD 1. On AIX that is wrong,
and the build fails at link time:

subprocess.h:1265:19: warning: implicit declaration of function
  'posix_spawn_file_actions_addchdir_np'; did you mean 'posix_spawn_file_actions_addopen'?
ld: 0711-317 ERROR: Undefined symbol: .posix_spawn_file_actions_addchdir_np

The compiler's suggestion is worth noting: spawn.h is being read and the
sibling functions are declared. Exactly one is missing.

Is there any way to test for AIX? Yes, and cheaply. Select the
implementation through a macro rather than _AIX, and any Linux runner can
exercise the fork path:

-DSUBPROCESS_SPAWN_VIA_FORK=1   ->  441/441 on glibc

That is a better CI lever than -D_AIX, and it would have caught the build
error I reported earlier, which is still open on this branch.


What real AIX shows

On unpatched main, AIX needs -DSUBPROCESS_HAVE_CWD=0 merely to link, and
then fails 27 of 441 tests. Nine are a PowerPC property unrelated to this PR
(see below). The other 18 are these two, in all nine language modes:

create_ex_subprocess_create_failure_preserves_error
create_ex_subprocess_create_failure_does_not_leak_resources

  Expected : (subprocess_error_not_found) == (subprocess_create_ex(...))
    Actual : -4 vs 0

posix_spawn on AIX returns success for a binary that does not exist. So
SUBPROCESS_SPAWN_REPORTS_EXEC_ERRORS guesses wrong on AIX too, for the same
structural reason as SUBPROCESS_HAVE_CWD: the #else hands 1 to every
platform nobody thought about. This PR's error pipe fixes exactly those 18.

AIX is not the only one

Taken from each vendor's own spawn.h and libc, not from documentation:

declares
FreeBSD 13.1–15.0 ..._addchdir_np fine
NetBSD 10.0, 10.1 ..._addchdir, no _np handled by #102
NetBSD 9.3, 9.4 neither #102's guard has no version test
OpenBSD 7.7–7.9 neither unhandled
AIX 7.2 neither this PR

Where I got to

I have opened #112 with your commit e6cec1b included unchanged. It starts from
current main and resolves the conflict against #102, #104, #106 and #110
additively rather than replaying the restructuring: main's posix_spawn path
stays byte-identical and the fork path sits beside it, +183/-7 where this PR
is +227/-97, so no other platform can regress. On top of that the probe now asks
two questions — whether a chdir file action exists at all, and which spelling —
which covers OpenBSD and NetBSD 9 as well.

On AIX the result passes 441 of 441 with no override beyond -maix64.
Unchanged elsewhere: Linux glibc, musl and i386 441/441, Windows MSVC 387/387 in
x86 and x64 against both CRTs, clang with ASan and UBSan 441/441, and NetBSD
9.4/10.1, OpenBSD 7.9, FreeBSD 14.3 all compile clean against sysroots built from
the vendors' release sets. A test spawning from eight threads, 640 spawns, passes
on both paths under ASan — worth having, since fork() in a threaded process is
the risky part and the suite is single-threaded.

Two things that are not this PR's problem but block AIX in practice:

  • utest.h has no AIX branch and stops at #error Unsupported platform!, and it
    does not build 32-bit at all, which is GCC's default on AIX. Fixed in
    Support AIX in utest_ns() utest.h#189 and Fix 32-bit builds under -Wpedantic utest.h#188.
  • create_subprocess_fail_divzero cannot hold on PowerPC: divw/divd leave
    the result undefined and raise no exception, so the child exits 0. The test
    already excludes AArch64 for the same reason; RISC-V belongs there too. Also
    measured on ppc64le Linux, so it is architecture, not AIX.

@sheredom

Copy link
Copy Markdown
Owner

Closing in favour of #112

@sheredom sheredom closed this Aug 18, 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.

3 participants