;;; This is a "repear" program that merely waits for child processes ;;; to appear and "reap" them, i.e. read their exit status to let them ;;; exit. The program allows an arbitrary first argument that is ;;; indended for identifying the reaper process. format elf64 executable entry main ;;; Using mixed Data and Code segment for size squeeze segment readable writable executable ;;; Main entry point main: ;; if (getpid() != 1) exit 1; xor rax, rax mov al, 39 ; rax=39 syscall dec rax jnz exit ; exit(1) ;; Continue here for pid 1 only pid_1: ;; Block all signals ;; sigprocmask(SIG_BLOCK, &set, 0); ; rax is already 0 mov rdi, rax ; SIG_BLOCK = 0 lea rsi, [set] ; *set mov rdx, rax ; 0 mov r10, rax ; 0 mov al, 14 ; sys_rt_sigprocmask ; rax=14, rdi=0, rsi=[set], rdx=0, r10=0 syscall ;; loop waiting for children, and reading their exit status reaper: ;; first clear status area again cld xor rax, rax lea rdi, [status] mov rdx, rdi mov rcx, rax mov cl, status$end-status rep stosq ;; waitid( idtype, id, *status, options ) mov rdi, rax ; idtype_t idtype = P_ALL = 0 mov rsi, rax ; int id = 0 ;rdx = [status] ; siginfo_t* = &status mov al, 4 ; int options = WEXITED = 4 mov r10, rax mov al, 247 ; waitid ; rax=247, rdi=0, rsi=0, rdx=[status], r10=4 syscall add rax, 10 ; -10 = ECHILD (no child processes) jnz reaper exit: ; exit(1) xor rax, rax mov rdi, rax inc rdi mov al, 60 syscall ; exit(1) program ;; sigset_t set -- bit mask for sigprocmask set: dq -1 ; all bits set ;;; siginfo_t status -- all ignored status: rept 16 { dq ? } status$end: