x64-httpd/main.s

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