aboutsummaryrefslogtreecommitdiffstats
path: root/src/syscall.asm
diff options
context:
space:
mode:
authoruser <user@clank>2026-07-16 11:10:45 +0200
committeruser <user@clank>2026-07-16 11:10:45 +0200
commit2d3597c3a02f821bb364b8ecc23fc5949fca738d (patch)
tree714cc7463eb36306f44fcfd67fcf52de0c13b3d1 /src/syscall.asm
parentshell: I/O redirection (>/<) and pipes (|); rewrite shell in C (diff)
downloadgbos-2d3597c3a02f821bb364b8ecc23fc5949fca738d.tar.gz
gbos-2d3597c3a02f821bb364b8ecc23fc5949fca738d.tar.xz
gbos-2d3597c3a02f821bb364b8ecc23fc5949fca738d.zip
kill + ps: implement SYS_KILL (pid 1 immortal) and a ps tool
- PCB gains PROC_PROG (running program id), set by exec, inherited on fork. - sys_kill(pid): reject pid 1 (immortal) and unknown/dead pids; mark the target zombie, reparent its children to init, wake its parent if blocked in wait; schedule away if a process kills itself. Reuses FindPcbByPid/ReparentToInit. - sys_ps(slot,buf)->{pid,state,prog}; sys_progname(id) via NameTable reverse lookup. NameTable gains sh/ps/kill. - libc: kill/psget/progname; tools ps (pid state cmd) and kill <pid>. - verified: ps lists sh(B)+ps(R); kill 1 refused; kill 42 fails.
Diffstat (limited to '')
-rw-r--r--src/syscall.asm168
1 files changed, 167 insertions, 1 deletions
diff --git a/src/syscall.asm b/src/syscall.asm
index f149a76..0b47c05 100644
--- a/src/syscall.asm
+++ b/src/syscall.asm
@@ -43,7 +43,7 @@ SyscallTable:
dw sys_exec ; 6 EXEC
dw sys_wait ; 7 WAIT
dw sys_getpid ; 8 GETPID
- dw sys_nosys ; 9 KILL (TODO)
+ dw sys_kill ; 9 KILL
dw sys_nosys ; 10 BRK (TODO)
dw sys_yield ; 11 YIELD
dw sys_getb ; 12 GETB
@@ -54,6 +54,8 @@ SyscallTable:
dw sys_setin ; 17 SETIN
dw sys_setout ; 18 SETOUT
dw sys_lookup ; 19 LOOKUP
+ dw sys_ps ; 20 PS
+ dw sys_progname ; 21 PROGNAME
; -----------------------------------------------------------------------------
sys_nosys:
@@ -388,3 +390,167 @@ sys_wait:
.nochild
ld a, $FF
ret
+
+; =============================================================================
+; sys_kill(B = pid) -> A = 0 ok / $FF fail. pid 1 (init/shell) is immortal.
+; Terminates the target: mark zombie, reparent its children to init, wake its
+; parent if blocked in wait. If we killed ourselves, schedule away forever.
+; =============================================================================
+sys_kill::
+ ld a, b
+ cp INIT_PID
+ jr z, .fail ; init is immortal
+ call FindPcbByPid ; A=pid -> DE=&PCB, CF if not found (B preserved=pid)
+ jr c, .fail
+ ld a, [de] ; state
+ cp PS_FREE
+ jr z, .fail
+ cp PS_ZOMBIE
+ jr z, .fail ; already dead
+ ; mark ZOMBIE
+ ld a, PS_ZOMBIE
+ ld [de], a
+ ; PROC_EXIT = KILL_CODE
+ ld a, e
+ add PROC_EXIT
+ ld l, a
+ ld a, d
+ adc 0
+ ld h, a
+ ld a, KILL_CODE
+ ld [hl], a
+ ; victim's parent pid
+ ld a, e
+ add PROC_PARENT
+ ld l, a
+ ld a, d
+ adc 0
+ ld h, a
+ ld a, [hl]
+ ld [wKillParent], a
+ ; reparent victim's children to init (B still = victim pid)
+ ld a, b
+ ld [wExitMyPid], a
+ call ReparentToInit
+ ; wake victim's parent if it is blocked in wait()
+ ld a, [wKillParent]
+ call FindPcbByPid
+ jr c, .maybe_self
+ ld a, [de]
+ cp PS_BLOCKED
+ jr nz, .maybe_self
+ ld a, PS_READY
+ ld [de], a
+.maybe_self
+ ; if the victim is the current process, don't return to it
+ ld a, [wCurProc]
+ add PROC_PID
+ ld l, a
+ ld a, [wCurProc+1]
+ adc 0
+ ld h, a
+ ld a, [wExitMyPid]
+ cp [hl]
+ jr nz, .ok
+.dead
+ call SchedYield
+ jr .dead
+.ok
+ xor a
+ ret
+.fail
+ ld a, $FF
+ ret
+
+; =============================================================================
+; sys_ps(B = slot, DE = buf[3]) -> A = 1 if used (buf = pid,state,prog), else 0
+; =============================================================================
+sys_ps::
+ ld a, e
+ ld [wPsBuf], a
+ ld a, d
+ ld [wPsBuf+1], a
+ ld a, b
+ cp MAX_PROCS
+ jr nc, .no
+ call PcbPtr ; DE = &PCB[slot]
+ ld a, [de] ; state
+ cp PS_FREE
+ jr z, .no
+ ld a, [wPsBuf]
+ ld l, a
+ ld a, [wPsBuf+1]
+ ld h, a ; HL = buf
+ push de ; PCB
+ ld a, e
+ add PROC_PID
+ ld e, a
+ ld a, d
+ adc 0
+ ld d, a
+ ld a, [de] ; pid
+ ld [hl+], a
+ pop de
+ push de
+ ld a, [de] ; state
+ ld [hl+], a
+ pop de
+ ld a, e
+ add PROC_PROG
+ ld e, a
+ ld a, d
+ adc 0
+ ld d, a
+ ld a, [de] ; prog id
+ ld [hl], a
+ ld a, 1
+ ret
+.no
+ xor a
+ ret
+
+; =============================================================================
+; sys_progname(B = id, DE = namebuf) - copy the command name for a program id.
+; =============================================================================
+sys_progname::
+ ld hl, NameTable
+.l
+ ld a, [hl]
+ or a
+ jr z, .none
+ ld a, l
+ ld [wPnStart], a
+ ld a, h
+ ld [wPnStart+1], a
+.sk
+ ld a, [hl+]
+ or a
+ jr nz, .sk ; HL now at the id byte
+ ld a, [hl]
+ cp b
+ jr z, .match
+ inc hl ; skip id -> next entry
+ jr .l
+.match
+ ld a, [wPnStart]
+ ld l, a
+ ld a, [wPnStart+1]
+ ld h, a
+ ld b, 8
+.cp
+ ld a, [hl+]
+ ld [de], a
+ inc de
+ or a
+ jr z, .done
+ dec b
+ jr nz, .cp
+.done
+ ret
+.none
+ ld a, $3F ; '?'
+ ld [de], a
+ inc de
+ xor a
+ ld [de], a
+ ret