;================================================================================= ; sys_waitpid & sys_pause demonstration. ; ; Forks a child process, which either pauses or terminates depending whether a ; command-line parameter was supplied. Parent process meanwhile waits for child's ; status to change and reports about it: ; ; ------------------------------------------------ ; $ ./waitpid & ; [1] 4902 ; CHILD: My PID is 0x00001327 ; CHILD: Waiting for signals... ; $ kill -STOP 4903 ; PARENT: Child has been stopped (0x00000013) ; $ kill -CONT 4903 ; PARENT: Child has been resumed ; $ kill -TERM 4903 ; PARENT: Child has been killed (0x0000000f) ; [1]+ Done ./waitpid ; ------------------------------------------------ ; $ ./waitpid foo ; CHILD: My PID is 0x00003456 ; PARENT: Child exited with exit code 0x00000000 ; PARENT: 1st command-line argument was: foo ; ------------------------------------------------ ; ; The LSCR Project. ;================================================================================= format ELF include '../macros.inc' include '../../include/symbols.inc' include '../../include/structs.inc' extrn error_chk extrn dd2ascii_hex section '.text' executable public _start _start: mov eax, SYS_FORK int 0x80 mov [child_pid], eax ; sys_fork returns 0 to the child process, ; child's PID to the parent process, or ERRNO on error. ccall error_chk, <"SYS_FORK has failed: ">, exit test eax, eax jne parent mov eax, SYS_GETPID ; CHILD process int 0x80 ccall dd2ascii_hex, eax, child1_s+19 mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, child1_s mov edx, 28 int 0x80 pop ecx ; retrieve command-line arguments number cmp ecx, 1 ; exit if at least one command-line argument was supplied. jg exit mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, child2_s mov edx, 30 int 0x80 mov eax, SYS_PAUSE int 0x80 jmp exit parent: ; PARENT process mov eax, SYS_WAITPID ; wait for the child to change state mov ebx, [child_pid] mov ecx, status mov edx, WUNTRACED or WCONTINUED int 0x80 ccall error_chk, <"SYS_WAITPID has failed: ">, exit mov eax, [status] ; check whether the child has exited and eax, 0xff jz child_exited mov eax, [status] ; check whether the child has been resumed by a signal cmp ax, 0xffff je child_resumed mov eax, [status] ; check whether the child has been killed by a signal test al, al jz @f cmp al, 0x7f jne child_killed @@: mov eax, [status] ; check whether the child has been stopped by a signal cmp al, 0x7f je child_stopped child_resumed: mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, child_resumed_s mov edx, child_resumed_s_sz int 0x80 jmp parent child_stopped: mov eax, [status] ; extract the signal and continue waitpid-ing shr eax, 8 ccall dd2ascii_hex, eax, child_stopped_s+34 mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, child_stopped_s mov edx, child_stopped_s_sz int 0x80 jmp parent child_killed: mov eax, [status] ; print the signal and exit ccall dd2ascii_hex, eax, child_killed_s+33 mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, child_killed_s mov edx, child_killed_s_sz int 0x80 jmp exit child_exited: mov eax, [status] ; extract the exit code and exit shr eax, 8 ccall dd2ascii_hex, eax, child_killed_s+33 mov eax, SYS_WRITE mov ebx, STDOUT mov ecx, child_exited_s mov edx, child_exited_s_sz int 0x80 add esp, 8 ; null argument is argument count. first argument is the application name. ; we don't need them pop edi ; second argument is the first command-line argument ; for simplicity sake only this one is printed mov ecx, edi xor edx, edx ; calculate argument's length xor eax, eax @@: inc edx scasb jne @b mov [edi-1], byte 0xa mov eax, SYS_WRITE mov ebx, STDOUT int 0x80 exit: mov eax, SYS_EXIT xor ebx, ebx int 0x80 section '.data' writeable child_pid rd 1 status rd 1 child_exited_s db "PARENT: Child exited with exit code 0x00000000",0xa db "PARENT: 1st command-line argument was: " child_exited_s_sz = $-child_exited_s child_killed_s db "PARENT: Child has been killed (0x00000000)",0xa child_killed_s_sz = $-child_killed_s child_stopped_s db "PARENT: Child has been stopped (0x00000000)",0xa child_stopped_s_sz = $-child_stopped_s child_resumed_s db "PARENT: Child has been resumed",0xa child_resumed_s_sz = $-child_resumed_s child1_s db "CHILD: My PID is 0x00000000",0xa child2_s db "CHILD: Waiting for signals...",0xa child1_s_sz = $-child1_s