186 lines
3.4 KiB
ArmAsm
186 lines
3.4 KiB
ArmAsm
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
|
|
POLLERR equ 8
|
|
POLLNVAL equ 32
|
|
; TODO(?) POLLPRI: see poll(2), tcp(7)
|
|
SHUT_RDWR equ 2
|
|
|
|
;STATE_READING equ 0
|
|
;STATE_WRITING equ 1
|
|
|
|
pollfd_size equ 4 + 2 + 2 ; $ man 2 poll
|
|
pollfds_capacity equ 100
|
|
|
|
; fd, state, line_len, buffer_len, uri_len, buffer, uri
|
|
client_size equ 4 + 4 + 255 + 255
|
|
clients_capacity equ pollfds_capacity - 1
|
|
|
|
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
|
|
pollfds_len dq 0
|
|
clients_len dq 0
|
|
|
|
SECTION .bss
|
|
sockaddr resb sockaddr_size
|
|
pollfds resb pollfd_size * pollfds_capacity
|
|
clients resb (4 + client_size) * clients_capacity
|
|
|
|
SECTION .text
|
|
|
|
%include "server.s"
|
|
%include "readline.s"
|
|
%include "clients.s"
|
|
%include "pollfds.s"
|
|
%include "client.s"
|
|
|
|
_start:
|
|
call make_server
|
|
mov rbx, rax ; server fd
|
|
mov rdi, rbx
|
|
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 ; poll(2) returned error TODO
|
|
|
|
scan:
|
|
mov r15, 0
|
|
|
|
; Variables:
|
|
; r15 - pollfds index
|
|
; r14w - poll(2) revents
|
|
; r13d - fd
|
|
; r12 - client memory address
|
|
scan__loop:
|
|
cmp r15, [pollfds_len]
|
|
jge poll
|
|
mov r14w, [pollfds + r15 * pollfd_size + 6]
|
|
cmp r14w, 0
|
|
jne scan__found
|
|
add r15, 1
|
|
jmp scan__loop
|
|
|
|
scan__found:
|
|
mov r13, 0
|
|
mov r13d, [pollfds + r15 * pollfd_size]
|
|
cmp r13d, ebx
|
|
je scan__found__server
|
|
|
|
scan__found__client:
|
|
mov rdi, r13
|
|
call clients__search
|
|
mov r12, rax
|
|
cmp r12, 0
|
|
jl _client__not_stored
|
|
|
|
mov r10w, r14w
|
|
and r10w, POLLERR | POLLNVAL
|
|
cmp r10w, 0
|
|
jne _client__error
|
|
|
|
mov r10w, r14w
|
|
and r10w, POLLIN
|
|
cmp r10w, 0
|
|
jne _client__pollin
|
|
|
|
mov r10w, r14w
|
|
and r10w, POLLOUT
|
|
cmp r10w, 0
|
|
jne _client__pollout
|
|
|
|
; TODO what did poll(2) detect in this case?
|
|
add r15, 1
|
|
jmp scan__loop
|
|
|
|
_client__error:
|
|
mov rdi, r12
|
|
call clients__remove
|
|
|
|
_client__not_stored:
|
|
mov rdi, r13
|
|
call client__shutdown_close
|
|
mov rdi, r15
|
|
call pollfds__remove
|
|
jmp scan__loop
|
|
|
|
_client__pollin:
|
|
mov rdi, r13
|
|
mov rsi, r12
|
|
mov rdx, r15
|
|
call client__pollin
|
|
cmp rax, 0
|
|
jle _client__error
|
|
add r15, rax
|
|
jmp scan__loop
|
|
|
|
_client__pollout:
|
|
mov rdi, r13
|
|
mov rsi, r12
|
|
mov rdx, r15
|
|
call client__pollout
|
|
add r15, 1
|
|
jmp scan__loop
|
|
|
|
scan__found__server:
|
|
cmp r14w, POLLIN
|
|
jne exit
|
|
|
|
mov rax, SYS_ACCEPT
|
|
mov rdi, r13
|
|
mov rsi, 0
|
|
mov rdx, 0
|
|
syscall
|
|
cmp rax, 0
|
|
jl exit ; accept(2) returned error TODO
|
|
|
|
mov rdi, rax
|
|
push rdi
|
|
mov si, POLLIN
|
|
call pollfds__append
|
|
|
|
pop rdi
|
|
call clients__append
|
|
|
|
add r15, 1
|
|
jmp scan__loop
|
|
|
|
return:
|
|
ret
|
|
|
|
exit:
|
|
mov rax, SYS_EXIT
|
|
mov rdi, 255
|
|
syscall
|