diff --git a/client.s b/client.s index 9946311..d3a1e7a 100644 --- a/client.s +++ b/client.s @@ -70,226 +70,83 @@ client__pollin__line_too_long: jmp client__pollin__return +; Returns: +; rax - non-negative from write(2) ; Errors: -; rax - negative or zero - from write(2) +; rax - -1024 - no line was buffered +; rax - other negative - from write(2) ; Arguments: ; rdi - fd ; rsi - address of client within clients array ; rdx - pollfds index ; Variables: -; rbp - fd ; rbx - pollfds index ; r12 - address of client within clients array -; r13 - line start -; r14 - line end -; r15 - client buffer end -; r11 - client buffer, length of last incomplete line +; r13 - line length +; r11 - client buffer end of text after call to write(2) client__pollout: - push rbp push rbx push r12 push r13 - push r14 - push r15 - mov rbp, rdi mov rbx, rdx mov r12, rsi - mov r13, rsi - add r13, OFFSET_CLIENT_BUFFER - mov r15, r13 - add r15, 255 - mov rdi, rbp - mov rsi, r12 - call client__pollout__before_fresh_lines - - cmp rax, 0 - jle client__pollout__return - -client__pollout__scan: - mov rdi, r13 - mov rsi, 0 - mov sil, [r12 + OFFSET_CLIENT_BUFFER_LEN] + push rdi + mov rdi, r12 + add rdi, OFFSET_CLIENT_BUFFER + mov rsi, 255 call scanline + pop rdi + ; poll(2)'d for POLLOUT but we had no line buffered; + ; should be impossible cmp rax, 0 - jle client__pollout__set_pollin ; no lines left + je client__pollout__no_line - sub [r12 + OFFSET_CLIENT_BUFFER_LEN], al + mov r13, rax - ; line_end = line_start + line_len - mov r14, r13 - add r14, rax - - mov rdi, rbp + mov rax, SYS_WRITE mov rsi, r12 + add rsi, OFFSET_CLIENT_BUFFER mov rdx, r13 - mov rcx, r14 - sub rcx, r13 - call client__pollout__line - - mov r13, r14 - - cmp rax, 0 - jle client__pollout__shunt - jmp client__pollout__scan - -client__pollout__set_pollin: - mov word [pollfds + rbx * pollfd_size + 4], POLLIN - mov rax, 1 - -client__pollout__shunt: - mov r10, 0 - mov r11, 0 - mov r11b, [r12 + OFFSET_CLIENT_BUFFER_LEN] - add r11, r12 - add r11, OFFSET_CLIENT_BUFFER - sub r11, r13 - -client__pollout__shunt__loop: - cmp r10, r11 - jge client__pollout__shunt__finished - mov r8b, [r10 + r13] - mov [r10], r8b - add r10, 1 - jmp client__pollout__shunt__loop - -client__pollout__shunt__finished: - mov r10, r13 - sub r10, r12 - sub r10, OFFSET_CLIENT_BUFFER - -client__pollout__return: - pop r15 - pop r14 - pop r13 - pop r12 - pop rbx - pop rbp - ret - -; Errors: -; rax - -1024 - some scratch buffer bytes remain, stop write(2)ing -; rax - other negative or zero - from write(2) -; Arguments: -; rdi - fd -; rsi - address of client within clients array -client__pollout__before_fresh_lines: - mov rdx, 0 - mov dl, [rsi + OFFSET_CLIENT_SCRATCH_LEN] - - cmp rdx, 0 - jle client__pollout__before_fresh_lines__return__succ - - mov rax, SYS_WRITE - push rdx - add rsi, OFFSET_CLIENT_SCRATCH - push rsi syscall - pop rsi - pop rdx - - cmp rax, 0 - jle return - - sub [rsi - OFFSET_CLIENT_SCRATCH + OFFSET_CLIENT_SCRATCH_LEN], al - - mov r10, rsi - mov r11, rsi - add r11, rdx - sub r11, rax - -client__pollout__before_fresh_lines__shunt: - cmp r10, r11 - jge client__pollout__before_fresh_lines__return - mov r8b, [r10 + rax] - mov [r10], r8b - add r10, 1 - jmp client__pollout__before_fresh_lines__shunt - -client__pollout__before_fresh_lines__return: - cmp rax, rdx - jl client__pollout__before_fresh_lines__return__fail - -client__pollout__before_fresh_lines__return__succ: - mov rax, 1 - ret - -client__pollout__before_fresh_lines__return__fail: - mov rax, -1024 - ret - -; Errors: -; rax - negative or zero - from write(2) -; Arguments: -; rdi - fd -; rsi - address of client within clients array -; rdx - line start -; rcx - line length -; Variables: -; rsi - client scratch -; r10 - line write(2) end -; r9 - line end -; Assumptions: -; scratch is empty, bc it was emptied by client__pollout__before_fresh_lines -; we must deal with the whole line we are given -client__pollout__line: - ; TODO we've got a line - ; - try writing it - ; - if socket is fucked: return - ; - if ok: cool - ; - if couldn't do the whole thing: you have scratch available, if it's needed for the protocol - - push rdx - push rcx - - mov rax, SYS_WRITE - mov rsi, rdx - mov rdx, rcx - syscall - - pop rcx - pop rdx - - ; TODO continue here also not sure calling fn is correct yet - ; check that changes to server.s haven't fucked anything up - ; error from write(2) cmp rax, 0 - jl client__pollout__line__error + jl client__pollout__return - cmp rax, rcx - jl client__pollout__line__incomplete + mov r10, r12 + mov r11, 0 + mov r11b, [r12 + OFFSET_CLIENT_BUFFER_LEN] + add r11, r12 + sub r11, rax - mov rax, 1 +client__pollout__shunt: + cmp r10, r11 + jge client__pollout__shunt__finished + mov r8b, [r10 + rax] + mov [r10], r8b + add r10, 1 + jmp client__pollout__shunt + +client__pollout__shunt__finished: + ; buffer_len -= rax + sub [r12 + OFFSET_CLIENT_BUFFER_LEN], al + cmp rax, r13 + jl client__pollout__return + mov word [pollfds + rbx * pollfd_size + 4], POLLIN + +client__pollout__return: + pop r13 + pop r12 + pop rbx ret -client__pollout__line__error: - mov r10, 0 - jmp client__pollout__line__write_scratch +client__pollout__no_line: + mov rax, -1024 + jmp client__pollout__return -client__pollout__line__incomplete: - mov r10, rax - -client__pollout__line__write_scratch: - add rsi, OFFSET_CLIENT_SCRATCH - add r10, rdx - mov r11, 0 - mov r9, rcx - add r9, rdx - -client__pollout__line__write_scratch__loop: - cmp r10, r9 - jge return - mov r8b, [r10 + r11] - mov [rsi + r11], r8b - add r11, 1 - jmp client__pollout__line__write_scratch__loop - - -; Arguments: ; rdi - fd client__shutdown_close: mov rax, SYS_SHUTDOWN diff --git a/constants.c b/constants.c index 3a8123c..8239355 100644 --- a/constants.c +++ b/constants.c @@ -2,7 +2,6 @@ #include #include #include -#include // printf("x %d\n", x); void main() { @@ -18,6 +17,4 @@ void main() { printf("POLLERR %d\n", POLLERR); printf("POLLNVAL %d\n", POLLNVAL); printf("SHUT_RDWR %d\n", SHUT_RDWR); - printf("EAGAIN %d\n", EAGAIN); - printf("EWOULDBLOCK %d\n", EWOULDBLOCK); } diff --git a/main.s b/main.s index d78bb66..ffa5496 100644 --- a/main.s +++ b/main.s @@ -26,7 +26,6 @@ POLLERR equ 8 POLLNVAL equ 32 ; TODO(?) POLLPRI: see poll(2), tcp(7) SHUT_RDWR equ 2 -EAGAIN equ -11 ;STATE_READING equ 0 ;STATE_WRITING equ 1 @@ -35,18 +34,14 @@ EAGAIN equ -11 OFFSET_CLIENT_FD equ 0 OFFSET_CLIENT_STATE equ 4 OFFSET_CLIENT_BUFFER_LEN equ 5 -OFFSET_CLIENT_SCRATCH_LEN equ 6 -OFFSET_CLIENT_BUFFER equ 7 -OFFSET_CLIENT_SCRATCH equ 7 + client_buffer_size +OFFSET_CLIENT_BUFFER equ 6 pollfd_size equ 4 + 2 + 2 ; $ man 2 poll pollfds_capacity equ 100 client_buffer_size equ 255 -client_scratch_size equ 255 - -; fd, state, buffer_len, scratch_len, buffer, scratch -client_size equ 4 + 2 + client_buffer_size + client_scratch_size +; fd, state, buffer_len, buffer +client_size equ 4 + 2 + client_buffer_size clients_capacity equ pollfds_capacity - 1 SECTION .data @@ -163,12 +158,8 @@ _client__pollout: mov rsi, r12 mov rdx, r15 call client__pollout - cmp rax, EAGAIN - je _client__pollout__finished cmp rax, 0 jle _client__error_or_eof - -_client__pollout__finished: add r15, 1 jmp scan__loop diff --git a/server.s b/server.s index fc2d1c7..baea35b 100644 --- a/server.s +++ b/server.s @@ -9,61 +9,53 @@ make_server: mov rsi, SOCK_STREAM mov rdx, 0 syscall + push rax - push r15 - mov r15, rax - - mov rdi, r15 call nonblocking - - mov rdi, r15 call make_sockaddr + pop r10 mov rax, SYS_BIND - mov rdi, r15 + mov rdi, r10 mov rsi, sockaddr mov rdx, sockaddr_size syscall mov rax, SYS_LISTEN - mov rdi, r15 + mov rdi, r10 mov rsi, 100 syscall - mov rax, r15 - pop r15 + mov rax, r10 ret -; rdi - fd nonblocking: - push r15 - mov r15, rdi + mov r10, rax mov rax, SYS_FCNTL - mov rdi, r15 + mov rdi, r10 mov rsi, F_GETFL syscall - mov r10, rax - or r10, O_NONBLOCK + mov r11, rax + xor r11, O_NONBLOCK mov rax, SYS_FCNTL - mov rdi, r15 + mov rdi, r10 mov rsi, F_SETFL - mov rdx, r10 + mov rdx, r11 syscall - pop r15 ret make_sockaddr: mov word [sockaddr], AF_UNIX - mov r10, 0 + mov rax, 0 make_sockaddr__copy_server_path: - cmp r10, server_path_len + cmp rax, server_path_len jge return - mov r8b, [server_path + r10] - mov [sockaddr + 2 + r10], r8b - add r10, 1 + mov r10, [server_path + rax] + mov [sockaddr + rax + 2], r10 + add rax, 8 jmp make_sockaddr__copy_server_path