-
Notifications
You must be signed in to change notification settings - Fork 0
Phase 18 arexx integration
Part of the Amiga port design log.
ARexx is the Amiga IPC mechanism: every well-behaved app exposes an ARexx
port. Both directions implemented. (Phase 32 later adds rexx_exists,
rexx_list, and a persistent RexxClient on top of this surface.)
Five C primitives in modamiga.c, RexxMessage facade in amiga.py:
name = amiga.rexx_open() # opens MICROPYTHON.1 (or .N)
while True:
msg = amiga.rexx_recv(timeout_ms=1000)
if msg is None: continue
try: msg.reply(str(eval(msg.command.decode("ascii"))), rc=0)
except Exception as e: msg.reply(str(e), rc=10)
amiga.rexx_close()
amiga.rexx_serve(lambda cmd: eval(cmd)) # ready-made dispatcher-
rexx_open(stem="MICROPYTHON")finds the lowest free.Nsuffix underForbid()/Permit(),CreateMsgPort()+AddPort(). -
rexx_close()drains the queue (replying rc=20 to anything still queued so a hungrxdoesn't stay blocked),RemPort,DeleteMsgPort, closesrexxsyslib.libraryif opened. Called frommain.con exit as a safety net. -
rexx_recv(timeout_ms=None)polls thenWait()s. The Phase 25 asynctimer.deviceport supplies the timeout signal bit;SIGBREAKF_CTRL_Cis always ORed in and raisesKeyboardInterruptif it fires. -
RexxMessage.reply(result=None, rc=0, secondary=0)setsrm_Result1=rc. Ifrc == 0and result non-None, lazy-opensrexxsyslib.library,CreateArgstringover the bytes, stores inrm_Result2; otherwisesecondarygoes intorm_Result2.ReplyMsg.__del__sends an automatic rc=20 reply if the script forgets — a forgotten reply would block the sender forever.
result = amiga.rexx("PPAINT.1", "ScreenToFront") # bytes
rc, result = amiga.rexx("HOST.1", "DoIt", check=False) # (rc, result|None)Textbook send-and-wait: FindPort → lazy OpenLibrary("rexxsyslib.library")
(cached, two-way scripts pay one open) → CreateMsgPort for private reply
port → CreateRexxMsg → CreateArgstring for the command → rm_Action = RXCOMM | RXFF_RESULT → PutMsg → Wait(reply | CTRL_C) → unpack
rm_Result1/rm_Result2, copy result bytes via mp_obj_new_bytes +
LengthArgstring, DeleteArgstring both → DeleteMsgPort.
Ctrl+C is deferred. Once PutMsg is in flight we can't tear down the
reply port — the host would PutMsg into freed memory. The wait latches
the CTRL_C bit but keeps spinning until the reply is in hand; then
KeyboardInterrupt is raised before returning.
Lazy-opened. So import amiga still works, the inbound port works for
rc-only replies, but:
-
RexxMessage.reply(result="...", rc=0)→ replies rc=10 to sender, raisesOSError("rexxsyslib.library unavailable"). -
amiga.rexx(host, command)→ raisesOSError(...)before any send.
call open(...), call writeln(...), call close(...) each clobber the
result special variable. Any rx script wanting to inspect the host
reply must snapshot it immediately after address:
options results
address MICROPYTHON.1 'some command'
saved_rc = rc
saved_result = result