Compare commits

..

No commits in common. "fc1cc26b0f1374b99c841fad0f32f6fba9355fe7" and "2fea95e10025d1ef256413cae6fd897c8db423a5" have entirely different histories.

4 changed files with 64 additions and 227 deletions

233
client.s
View file

@ -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

View file

@ -2,7 +2,6 @@
#include <sys/socket.h>
#include <fcntl.h>
#include <poll.h>
#include <errno.h>
// 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);
}

15
main.s
View file

@ -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

View file

@ -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