Compare commits
6 commits
2fea95e100
...
fc1cc26b0f
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fc1cc26b0f | ||
![]() |
c16c82b15f | ||
![]() |
e31c9452c8 | ||
![]() |
21153b7d14 | ||
![]() |
2a59922c01 | ||
![]() |
56715c3079 |
4 changed files with 221 additions and 58 deletions
221
client.s
221
client.s
|
@ -70,83 +70,226 @@ client__pollin__line_too_long:
|
||||||
jmp client__pollin__return
|
jmp client__pollin__return
|
||||||
|
|
||||||
|
|
||||||
; Returns:
|
|
||||||
; rax - non-negative from write(2)
|
|
||||||
; Errors:
|
; Errors:
|
||||||
; rax - -1024 - no line was buffered
|
; rax - negative or zero - from write(2)
|
||||||
; rax - other negative - from write(2)
|
|
||||||
; Arguments:
|
; Arguments:
|
||||||
; rdi - fd
|
; rdi - fd
|
||||||
; rsi - address of client within clients array
|
; rsi - address of client within clients array
|
||||||
; rdx - pollfds index
|
; rdx - pollfds index
|
||||||
; Variables:
|
; Variables:
|
||||||
|
; rbp - fd
|
||||||
; rbx - pollfds index
|
; rbx - pollfds index
|
||||||
; r12 - address of client within clients array
|
; r12 - address of client within clients array
|
||||||
; r13 - line length
|
; r13 - line start
|
||||||
; r11 - client buffer end of text after call to write(2)
|
; r14 - line end
|
||||||
|
; r15 - client buffer end
|
||||||
|
; r11 - client buffer, length of last incomplete line
|
||||||
client__pollout:
|
client__pollout:
|
||||||
|
push rbp
|
||||||
push rbx
|
push rbx
|
||||||
push r12
|
push r12
|
||||||
push r13
|
push r13
|
||||||
|
push r14
|
||||||
|
push r15
|
||||||
|
|
||||||
|
mov rbp, rdi
|
||||||
mov rbx, rdx
|
mov rbx, rdx
|
||||||
mov r12, rsi
|
mov r12, rsi
|
||||||
|
mov r13, rsi
|
||||||
|
add r13, OFFSET_CLIENT_BUFFER
|
||||||
|
mov r15, r13
|
||||||
|
add r15, 255
|
||||||
|
|
||||||
push rdi
|
mov rdi, rbp
|
||||||
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
|
|
||||||
je client__pollout__no_line
|
|
||||||
|
|
||||||
mov r13, rax
|
|
||||||
|
|
||||||
mov rax, SYS_WRITE
|
|
||||||
mov rsi, r12
|
mov rsi, r12
|
||||||
add rsi, OFFSET_CLIENT_BUFFER
|
call client__pollout__before_fresh_lines
|
||||||
mov rdx, r13
|
|
||||||
syscall
|
|
||||||
|
|
||||||
; error from write(2)
|
|
||||||
cmp rax, 0
|
cmp rax, 0
|
||||||
jl client__pollout__return
|
jle client__pollout__return
|
||||||
|
|
||||||
mov r10, r12
|
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 r11, 0
|
||||||
mov r11b, [r12 + OFFSET_CLIENT_BUFFER_LEN]
|
mov r11b, [r12 + OFFSET_CLIENT_BUFFER_LEN]
|
||||||
add r11, r12
|
add r11, r12
|
||||||
sub r11, rax
|
add r11, OFFSET_CLIENT_BUFFER
|
||||||
|
sub r11, r13
|
||||||
|
|
||||||
client__pollout__shunt:
|
client__pollout__shunt__loop:
|
||||||
cmp r10, r11
|
cmp r10, r11
|
||||||
jge client__pollout__shunt__finished
|
jge client__pollout__shunt__finished
|
||||||
mov r8b, [r10 + rax]
|
mov r8b, [r10 + r13]
|
||||||
mov [r10], r8b
|
mov [r10], r8b
|
||||||
add r10, 1
|
add r10, 1
|
||||||
jmp client__pollout__shunt
|
jmp client__pollout__shunt__loop
|
||||||
|
|
||||||
client__pollout__shunt__finished:
|
client__pollout__shunt__finished:
|
||||||
; buffer_len -= rax
|
mov r10, r13
|
||||||
sub [r12 + OFFSET_CLIENT_BUFFER_LEN], al
|
sub r10, r12
|
||||||
cmp rax, r13
|
sub r10, OFFSET_CLIENT_BUFFER
|
||||||
jl client__pollout__return
|
|
||||||
mov word [pollfds + rbx * pollfd_size + 4], POLLIN
|
|
||||||
|
|
||||||
client__pollout__return:
|
client__pollout__return:
|
||||||
|
pop r15
|
||||||
|
pop r14
|
||||||
pop r13
|
pop r13
|
||||||
pop r12
|
pop r12
|
||||||
pop rbx
|
pop rbx
|
||||||
|
pop rbp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
client__pollout__no_line:
|
; Errors:
|
||||||
mov rax, -1024
|
; rax - -1024 - some scratch buffer bytes remain, stop write(2)ing
|
||||||
jmp client__pollout__return
|
; 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
|
; rdi - fd
|
||||||
client__shutdown_close:
|
client__shutdown_close:
|
||||||
mov rax, SYS_SHUTDOWN
|
mov rax, SYS_SHUTDOWN
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
// printf("x %d\n", x);
|
// printf("x %d\n", x);
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -17,4 +18,6 @@ void main() {
|
||||||
printf("POLLERR %d\n", POLLERR);
|
printf("POLLERR %d\n", POLLERR);
|
||||||
printf("POLLNVAL %d\n", POLLNVAL);
|
printf("POLLNVAL %d\n", POLLNVAL);
|
||||||
printf("SHUT_RDWR %d\n", SHUT_RDWR);
|
printf("SHUT_RDWR %d\n", SHUT_RDWR);
|
||||||
|
printf("EAGAIN %d\n", EAGAIN);
|
||||||
|
printf("EWOULDBLOCK %d\n", EWOULDBLOCK);
|
||||||
}
|
}
|
||||||
|
|
15
main.s
15
main.s
|
@ -26,6 +26,7 @@ POLLERR equ 8
|
||||||
POLLNVAL equ 32
|
POLLNVAL equ 32
|
||||||
; TODO(?) POLLPRI: see poll(2), tcp(7)
|
; TODO(?) POLLPRI: see poll(2), tcp(7)
|
||||||
SHUT_RDWR equ 2
|
SHUT_RDWR equ 2
|
||||||
|
EAGAIN equ -11
|
||||||
|
|
||||||
;STATE_READING equ 0
|
;STATE_READING equ 0
|
||||||
;STATE_WRITING equ 1
|
;STATE_WRITING equ 1
|
||||||
|
@ -34,14 +35,18 @@ SHUT_RDWR equ 2
|
||||||
OFFSET_CLIENT_FD equ 0
|
OFFSET_CLIENT_FD equ 0
|
||||||
OFFSET_CLIENT_STATE equ 4
|
OFFSET_CLIENT_STATE equ 4
|
||||||
OFFSET_CLIENT_BUFFER_LEN equ 5
|
OFFSET_CLIENT_BUFFER_LEN equ 5
|
||||||
OFFSET_CLIENT_BUFFER equ 6
|
OFFSET_CLIENT_SCRATCH_LEN equ 6
|
||||||
|
OFFSET_CLIENT_BUFFER equ 7
|
||||||
|
OFFSET_CLIENT_SCRATCH equ 7 + client_buffer_size
|
||||||
|
|
||||||
pollfd_size equ 4 + 2 + 2 ; $ man 2 poll
|
pollfd_size equ 4 + 2 + 2 ; $ man 2 poll
|
||||||
pollfds_capacity equ 100
|
pollfds_capacity equ 100
|
||||||
|
|
||||||
client_buffer_size equ 255
|
client_buffer_size equ 255
|
||||||
; fd, state, buffer_len, buffer
|
client_scratch_size equ 255
|
||||||
client_size equ 4 + 2 + client_buffer_size
|
|
||||||
|
; fd, state, buffer_len, scratch_len, buffer, scratch
|
||||||
|
client_size equ 4 + 2 + client_buffer_size + client_scratch_size
|
||||||
clients_capacity equ pollfds_capacity - 1
|
clients_capacity equ pollfds_capacity - 1
|
||||||
|
|
||||||
SECTION .data
|
SECTION .data
|
||||||
|
@ -158,8 +163,12 @@ _client__pollout:
|
||||||
mov rsi, r12
|
mov rsi, r12
|
||||||
mov rdx, r15
|
mov rdx, r15
|
||||||
call client__pollout
|
call client__pollout
|
||||||
|
cmp rax, EAGAIN
|
||||||
|
je _client__pollout__finished
|
||||||
cmp rax, 0
|
cmp rax, 0
|
||||||
jle _client__error_or_eof
|
jle _client__error_or_eof
|
||||||
|
|
||||||
|
_client__pollout__finished:
|
||||||
add r15, 1
|
add r15, 1
|
||||||
jmp scan__loop
|
jmp scan__loop
|
||||||
|
|
||||||
|
|
40
server.s
40
server.s
|
@ -9,53 +9,61 @@ make_server:
|
||||||
mov rsi, SOCK_STREAM
|
mov rsi, SOCK_STREAM
|
||||||
mov rdx, 0
|
mov rdx, 0
|
||||||
syscall
|
syscall
|
||||||
push rax
|
|
||||||
|
|
||||||
|
push r15
|
||||||
|
mov r15, rax
|
||||||
|
|
||||||
|
mov rdi, r15
|
||||||
call nonblocking
|
call nonblocking
|
||||||
|
|
||||||
|
mov rdi, r15
|
||||||
call make_sockaddr
|
call make_sockaddr
|
||||||
pop r10
|
|
||||||
|
|
||||||
mov rax, SYS_BIND
|
mov rax, SYS_BIND
|
||||||
mov rdi, r10
|
mov rdi, r15
|
||||||
mov rsi, sockaddr
|
mov rsi, sockaddr
|
||||||
mov rdx, sockaddr_size
|
mov rdx, sockaddr_size
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
mov rax, SYS_LISTEN
|
mov rax, SYS_LISTEN
|
||||||
mov rdi, r10
|
mov rdi, r15
|
||||||
mov rsi, 100
|
mov rsi, 100
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
mov rax, r10
|
mov rax, r15
|
||||||
|
pop r15
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; rdi - fd
|
||||||
nonblocking:
|
nonblocking:
|
||||||
mov r10, rax
|
push r15
|
||||||
|
mov r15, rdi
|
||||||
|
|
||||||
mov rax, SYS_FCNTL
|
mov rax, SYS_FCNTL
|
||||||
mov rdi, r10
|
mov rdi, r15
|
||||||
mov rsi, F_GETFL
|
mov rsi, F_GETFL
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
mov r11, rax
|
mov r10, rax
|
||||||
xor r11, O_NONBLOCK
|
or r10, O_NONBLOCK
|
||||||
|
|
||||||
mov rax, SYS_FCNTL
|
mov rax, SYS_FCNTL
|
||||||
mov rdi, r10
|
mov rdi, r15
|
||||||
mov rsi, F_SETFL
|
mov rsi, F_SETFL
|
||||||
mov rdx, r11
|
mov rdx, r10
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
|
pop r15
|
||||||
ret
|
ret
|
||||||
|
|
||||||
make_sockaddr:
|
make_sockaddr:
|
||||||
mov word [sockaddr], AF_UNIX
|
mov word [sockaddr], AF_UNIX
|
||||||
mov rax, 0
|
mov r10, 0
|
||||||
|
|
||||||
make_sockaddr__copy_server_path:
|
make_sockaddr__copy_server_path:
|
||||||
cmp rax, server_path_len
|
cmp r10, server_path_len
|
||||||
jge return
|
jge return
|
||||||
mov r10, [server_path + rax]
|
mov r8b, [server_path + r10]
|
||||||
mov [sockaddr + rax + 2], r10
|
mov [sockaddr + 2 + r10], r8b
|
||||||
add rax, 8
|
add r10, 1
|
||||||
jmp make_sockaddr__copy_server_path
|
jmp make_sockaddr__copy_server_path
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue