; ____________________________________________________________________
;|                                                                    |
;| This file is part of the project:                                  |
;|                                                                    |
;| ..::FreshLib::.. - portable, assembler based toolkit.              |
;| __________________________________________________________________ |
;|                                                                    |
;|                          This file                                 |
;|                          ~~~~~~~~~                                 |
;|   Author: pelaillo, John Found                                     |
;|                                                                    |
;|   Title: process.asm  Process management library. OS dependent     |
;|                                                                    |
;|   OS: Linux                                                        |
;|                                                                    |
;|   Notes and changes: This library provides unified interface to    |
;|                      access processes for Linux OS                 |
;|                                                                    |
;|____________________________________________________________________|


; Terminate current process
; Returns: eax = 0
proc Terminate,.exit_code
begin
        mov     eax, sys_exit
        mov     ebx, [.exit_code]
        int     0x80
        return
endp



__ThreadStackSize = 1024 * 1024  ; 1Mbyte for the thread stack

; Creates a new execution thread
; Returns: CF=1 if error.
;          CF=0, eax = pid of the new process being created
proc ThreadCreate, .ptr_to_function, .ptr_to_args
begin
        push    ebx ecx edx

        push    0    ; offset
        push    -1    ; file
        push    MAP_ANONYMOUS or MAP_PRIVATE or MAP_GROWSDOWN or MAP_STACK
        push    PROT_READ or PROT_WRITE
        push    __ThreadStackSize
        push    0       ; address

        mov     eax, sys_old_mmap    ; mmap
        mov     ebx, esp
        int $80
        add     esp, 6*4

        cmp     eax, $ffffff00
        jae     .error

        lea     ecx, [eax+__ThreadStackSize-12]

; transfer arguments in the new stack.
        mov     eax, [.ptr_to_function]
        mov     [ecx], eax
        mov     eax, [.ptr_to_args]
        mov     [ecx+4], eax

        mov     eax, sys_clone
        mov     ebx, CLONE_VM or CLONE_FILES or CLONE_FS or CLONE_SIGHAND

        int 0x80
        cmp     eax,-1
        je      .error

        test    eax, eax
        jz      .is_clone

        clc
        pop     edx ecx ebx
        return

; this is the clone process - call the thread.
.is_clone:
        pop     eax
        call    eax       ; the argument is already in the stack.
        mov     esi, eax  ; the thread procedure can return exit code. Save it in esi.

; release the stack.
        mov     eax, sys_munmap
        lea     ebx, [esp-__ThreadStackSize+4]
        mov     ecx, __ThreadStackSize
        int $80

; and exit the process
        mov     ebx, esi
        mov     eax, sys_exit
        int     0x80

        int3    ; here the thread ends with exit code of eax

.error:
        stc
        pop     edx ecx ebx
        return
endp
