global _start ; constants SYS_READ equ 0 SYS_WRITE equ 1 SYS_CLOSE equ 3 SYS_POLL equ 7 SYS_SENDFILE equ 40 SYS_SOCKET equ 41 SYS_ACCEPT equ 43 SYS_SHUTDOWN equ 48 SYS_BIND equ 49 SYS_LISTEN equ 50 SYS_EXIT equ 60 SYS_FCNTL equ 72 SYS_UNLINK equ 87 STDOUT equ 1 AF_UNIX equ 1 SOCK_STREAM equ 1 F_GETFL equ 3 F_SETFL equ 4 O_NONBLOCK equ 2048 POLLIN equ 1 POLLOUT equ 4 SHUT_RDWR equ 2 pollfd_size equ 4 + 2 + 2 ; $ man 2 poll pollfds_capacity equ 100 SECTION .data server_path db "server.sock", 0x00 server_path_len equ $ - server_path sockaddr_size equ 2 + 108 ; $ man 7 unix goodbye db "goodbye", 0x0a goodbye_len equ $ - goodbye SECTION .bss sockaddr resb sockaddr_size pollfds resb pollfd_size * pollfds_capacity pollfds_len resb 8 SECTION .text %include "server.s" _start: call make_server mov rbx, rax ; server fd mov rdi, rax mov rsi, POLLIN call pollfds__append poll: mov rax, SYS_POLL mov rdi, pollfds mov rsi, [pollfds_len] mov rdx, 5000 syscall cmp rax, 0 je poll jl exit mov rdi, rbx ; rdi - server fd pollfds__scan: mov r15, 0 pollfds__scan__loop: cmp r15, [pollfds_len] jge poll mov r10w, [pollfds + r15 * pollfd_size + 6] cmp r10w, 0 jne pollfds__scan__found add r15, 1 jmp pollfds__scan__loop pollfds__scan__found: mov r14, 0 mov r14d, [pollfds + r15 * pollfd_size] cmp r14d, edi je pollfds__scan__found__server pollfds__scan__found__client: push rdi mov rax, SYS_WRITE mov rdi, 0 mov edi, r14d mov rsi, goodbye mov rdx, goodbye_len syscall cmp rax, 0 jl exit mov rax, SYS_SHUTDOWN mov rdi, 0 mov edi, r14d mov rsi, SHUT_RDWR syscall mov rax, SYS_CLOSE mov rdi, 0 mov edi, r14d syscall mov rdi, r15 call pollfds__remove pop rdi jmp pollfds__scan__loop pollfds__scan__found__server: push rdi mov rax, SYS_ACCEPT mov rsi, 0 mov rdx, 0 syscall cmp rax, 0 jl exit mov rdi, rax mov si, POLLIN | POLLOUT call pollfds__append pop rdi add r15, 1 jmp pollfds__scan__loop ; edi - fd ; si - events pollfds__append: mov r10, [pollfds_len] mov [pollfds + r10 * pollfd_size], edi mov [pollfds + r10 * pollfd_size + 4], si add r10, 1 mov [pollfds_len], r10 ret ; rdi - pollfds array index to remove pollfds__remove: mov r11, [pollfds_len] cmp rdi, r10 jge return ; XXX index out of bounds, do some other error? cmp r11, 1 jle pollfds__clear mov r10, [pollfds + (r11 - 1) * pollfd_size] mov [pollfds + rdi * pollfd_size], r10 sub r11, 1 mov [pollfds_len], r11 ret pollfds__clear: mov r10, 0 mov [pollfds_len], r10 ret return: ret exit: mov rax, SYS_EXIT mov rdi, 0 syscall