global _start ; constants SYS_READ equ 0 SYS_WRITE equ 1 SYS_POLL equ 7 SYS_SENDFILE equ 40 SYS_SOCKET equ 41 SYS_ACCEPT equ 43 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 pollfd_size equ 4 + 2 + 2 ; $ man 2 poll pollfds_capacity equ 100 SECTION .data hello db "Hello world!", 0x0a hello_len equ $ - hello server_path db "server.sock", 0x00 server_path_len equ $ - hello sockaddr_size equ 2 + 108 ; $ man 7 unix SECTION .bss sockaddr resb sockaddr_size pollfds resb pollfd_size * pollfds_capacity SECTION .text _start: mov rax, SYS_WRITE mov rdi, STDOUT mov rsi, hello mov rdx, hello_len syscall call make_server mov rbx, 0 ; pollfd array length mov ebp, eax ; server fd mov rax, rbx mov edi, ebp mov si, POLLIN call pollfds__append mov rbx, rax mov rax, SYS_POLL mov rdi, pollfds mov rsi, rbx mov rdx, 5000 syscall exit: mov rax, SYS_EXIT mov rdi, 0 syscall accept: mov rdi, rax mov rax, SYS_ACCEPT mov rsi, 0 mov rdx, 0 syscall ret ; rax - array length ; edi - fd ; si - events ; Returns new array length in rax pollfds__append: mov [pollfds + rax], edi mov [pollfds + rax + 4], si add rax, 1 ret ; Returns new array length in rax ; rax - array length ; edi - fd pollfds__remove: mov r10d, edi mov rdi, 0 ; Variables: ; rax - array length ; rdi - array index ; r10d - fd ; r11d - pollfds[rdi].fd pollfds__remove__loop: cmp rdi, rax jge return ; fd was not found mov r11d, [pollfds + rdi * pollfd_size] add rdi, 1 cmp r11d, r10d jne pollfds__remove__loop sub rdi, 1 ; Returns new array length in rax ; rax - array length ; rdi - array index to remove pollfds__remove_index: cmp rax, 1 jle pollfds__clear mov r10d, [pollfds + (rax - 1) * pollfd_size] mov [pollfds + rdi * pollfd_size], r10d sub rax, 1 ret ; Returns new array length in rax ; rax - array length pollfds__clear: mov rax, 0 ret ; Returns (in rax) the server's file descriptor make_server: mov rax, SYS_UNLINK mov rdi, server_path syscall mov rax, SYS_SOCKET mov rdi, AF_UNIX mov rsi, SOCK_STREAM mov rdx, 0 syscall push rax call nonblocking call make_sockaddr pop r10 mov rax, SYS_BIND mov rdi, r10 mov rsi, sockaddr mov rdx, sockaddr_size syscall mov rax, SYS_LISTEN mov rdi, r10 mov rsi, 100 syscall mov rax, r10 ret nonblocking: mov r10, rax mov rax, SYS_FCNTL mov rdi, r10 mov rsi, F_GETFL syscall mov r11, rax xor r11, O_NONBLOCK mov rax, SYS_FCNTL mov rdi, r10 mov rsi, F_SETFL mov rdx, r11 syscall ret make_sockaddr: mov word [sockaddr], AF_UNIX mov rax, 0 make_sockaddr__copy_server_path: cmp rax, server_path_len jge return mov r10, [server_path + rax] mov [sockaddr + rax + 2], r10 add rax, 8 jmp make_sockaddr__copy_server_path return: ret