; Returns: ; rax - 0 ; Errors (in rax): ; rax - 0 - EOF ; rax - -1024 - line too long ; rax - other negative - from read(2) ; Arguments: ; rdi - fd ; rsi - address of client within clients array ; rdx - pollfds index ; Variables: ; rbx - pollfds index ; r12 - client buffer ; r13 - start of line scanning ; r14 - client buffer end client__pollin: push rbx push r12 push r13 push r14 mov rbx, rdx mov r12, rsi add r12, OFFSET_CLIENT_BUFFER mov r13, 0 mov r13b, [rsi + OFFSET_CLIENT_BUFFER_LEN] add r13, r12 mov r14, r12 add r14, 255 mov rax, SYS_READ mov rsi, r13 mov rdx, 255 sub dl, [rsi + OFFSET_CLIENT_BUFFER_LEN] syscall cmp rax, 0 jle client__pollin__return ; TODO verify this shit ; buffer_len += read(2) length add [r12 - OFFSET_CLIENT_BUFFER + OFFSET_CLIENT_BUFFER_LEN], al mov rdi, r13 mov rsi, rax call scanline cmp rax, 0 je client__pollin__no_line mov rax, 1 mov word [pollfds + rbx * pollfd_size + 4], POLLOUT client__pollin__return: pop r14 pop r13 pop r12 pop rbx ret client__pollin__no_line: mov r10, r13 add r10, rax cmp r10, r14 jge client__pollin__line_too_long mov rax, 1 jmp client__pollin__return client__pollin__line_too_long: mov rax, -1024 jmp client__pollin__return ; Errors: ; rax - negative or zero - 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 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] call scanline cmp rax, 0 jle client__pollout__set_pollin ; no lines left sub [r12 + OFFSET_CLIENT_BUFFER_LEN], al ; line_end = line_start + line_len mov r14, r13 add r14, rax mov rdi, rbp mov rsi, r12 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 cmp rax, rcx jl client__pollout__line__incomplete mov rax, 1 ret client__pollout__line__error: mov r10, 0 jmp client__pollout__line__write_scratch 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 push rdi mov rsi, SHUT_RDWR syscall mov rax, SYS_CLOSE pop rdi syscall ret