Skip to content

vms-947: implement sys$setddir (self-host MMK RTL prereq) - #413

Merged
baron-3dl merged 1 commit into
mainfrom
vms-947-sys-setddir
Aug 13, 2026
Merged

baron-3dl merged 1 commit into
mainfrom
vms-947-sys-setddir

Conversation

@baron-3dl

Copy link
Copy Markdown
Contributor

Summary

Implements SYS$SETDDIR (previously absent) — reads and optionally changes the process default directory string, the [dir] used to resolve relative file specifications. A hard RTL prereq for native MMK.EXE (parent vms-801; design anchor vms-52c / docs/design-self-host-mmk-spine.md). The vendored MadGoat MMK (tests/corpus/tier3-mmk/mmk.c) is a real consumer.

Semantics (clean-room, Rule 8)

Derived only from the OpenVMS System Services Reference ($SETDDIR) and the calling convention MMK exercises:

  • sys$setddir(new_dir, old_len, old_dir)
    • new_dir NULL → read-only (return current directory)
    • old_dir supplied → receive previous string (truncated to buffer); old_len = bytes written (MMK does old_def_dir[len]='\0')
    • old_len without old_dir → full current length
    • previous captured before the change (VMS order)
    • empty / over-long new spec → SS$_BADPARAM (no fake success — INV-DCL/INV-6)

Coordination with existing default-dir storage

OVMX keeps the process default directory in the PCB (pcb->default_dir) — the same store src/libvms/syssvc/sys_assign.c reads to resolve SYS$DISK / relative specs. sys$setddir reads and mutates that store via vms_pcb_get / vms_pcb_set_default_dir, so a change is observable by subsequent relative filespec resolution — not a per-call no-op. OVMX conflates device+directory into the one field; a bare bracketed [dir] keeps the current device prefix (mirrors SET DEFAULT / cmd_set_default), a full device:[dir] spec is stored verbatim. Declared OVMX-USERSPACE in the sys_misc.c register banner (the default directory is a per-process construct on real VMS too; no executive resource is faked) — test_userspace_service_register.sh passes.

Native-link

sys$setddir is a global text symbol in sys_misc (already in mk_libvms_shr.sh LIST), so it auto-exports into LIBVMS\$SHR.EXE's .vms\$sv vector. Verified via the alpine-musl OVMX_LINK_NATIVE reproduction: 9 artifacts, EM_X86_64, zero DT_NEEDED, and sys$setddir present in the .vms\$sv section.

Test

tests/libvms/test_setddir.c (test_libvms_setddir) — 19 assertions: read-only, set + return-previous, round-trip observability, full vs bracketed spec handling, set-only form, and both SS$_BADPARAM paths.

Verification

  • Debug ctest: exit 0 — 147 tests passed (12 e2e/QEMU-install tests skipped as standard), including test_libvms_setddir.
  • Native-link (x86_64 alpine-musl link_native_graph): green, symbol in .vms\$sv.
  • Userspace service register gate: PASS.

No starlet.h prototype added (matches existing convention — sys$setprv/sys$getsyi have none; MMK declares its own; native-link binds by symbol) to avoid perturbing the corpus conformance baseline.

🤖 Generated with Claude Code

SYS$SETDDIR reads and optionally changes the process default directory
string -- the [dir] used to resolve relative file specifications. Absent
until now; a hard prereq for native MMK.EXE (vms-801 / vms-52c anchor:
tests/corpus/tier3-mmk/mmk.c is a real consumer).

Semantics derived only from the OpenVMS System Services Reference
($SETDDIR) and the calling convention MMK exercises (clean-room, Rule 8):
  sys$setddir(new_dir, old_len, old_dir)
    - new_dir NULL           -> read-only (return current directory)
    - old_dir supplied       -> receive previous string (truncated to buf);
                                old_len = bytes written (MMK relies on this)
    - old_len w/o old_dir     -> full current length
    - previous captured BEFORE the change (VMS order)
    - empty / over-long new spec -> SS$_BADPARAM (no fake success, INV-DCL)

Coordination with existing default-dir storage: OVMX keeps the process
default directory in the PCB (pcb->default_dir), the same store
sys_assign.c reads to resolve SYS$DISK / relative specs. sys$setddir
reads and mutates that store via vms_pcb_get / vms_pcb_set_default_dir,
so a change is observable by subsequent relative filespec resolution --
not a per-call no-op. OVMX conflates device+directory into pcb->default_dir;
a bare bracketed "[dir]" keeps the current device prefix (mirrors SET
DEFAULT / cmd_set_default), a full device:[dir] spec is stored verbatim.
Declared OVMX-USERSPACE (the default directory is a per-process construct
on real VMS too; no executive resource is faked).

Native-link: sys$setddir is a global text symbol in sys_misc (already in
mk_libvms_shr.sh LIST), so it is auto-exported into LIBVMS$SHR.EXE's
.vms$sv vector -- verified via the alpine-musl OVMX_LINK_NATIVE
reproduction (9 artifacts, EM_X86_64, zero DT_NEEDED, symbol present).

Test: tests/libvms/test_setddir.c (test_libvms_setddir) -- 19 assertions
covering read-only, set+return-previous, round-trip observability, full
vs bracketed spec handling, set-only form, and both SS$_BADPARAM paths.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@baron-3dl
baron-3dl merged commit b01ab87 into main Aug 13, 2026
60 checks passed
baron-3dl added a commit that referenced this pull request Aug 13, 2026
#445)

Bump OVMX_PRODUCT_VERSION V0.4 → V0.4-1. 24 PRs / 32 commits since V0.4,
packed across dimensions (point release toward the 0.5 milestone):

  self-host (R7)  #409 lib$tparse · #411 CLI$ compiled-CLD · #413 sys$setddir
                  #414 lib$get_foreign · #415 sys$filescan (RTL foundation)
                  #418 parse_tables.mar→C (spine #2) · #429 LIBRARIAN.EXE+.OLB (spine #3)
                  #435 shareable-vector freeze (GSMATCH stability)
  authenticity    #421 veracity rubric (Q1 oracle-source/Q2 real-inject) · #424 30 oracle-pinned constants
                  #433 rmsdef.h 74 fabricated RMS codes → oracle
  UX/DCL/RMS      #422 SHOW CLUSTER real membership · #441 DCL per-@-level local scope
                  #442 RMS XAB dates → VMS 1858-epoch quadword
  networking      #419 virtio NIC (user-mode default + opt-in tap/bridge)
  docs            #423 clustering release train
  + swept: other threads' merged work on main since V0.4

Clustering config-authoring UX (vms-098) + its public-manual grounding gate
remain 0.5 (minor) deliverables — not triggered by this point cut.

Co-authored-by: alice <alice@workspace.local>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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