Adds fread(), fseek()
This commit is contained in:
@@ -75,3 +75,7 @@ section .rodata
|
||||
S_IFIFO equ 0010000q ; FIFO
|
||||
S_IFLNK equ 0120000q ; Symbolic link
|
||||
S_IFSOCK equ 0140000q ; Socket
|
||||
; Seek options
|
||||
SEEK_SET equ 0
|
||||
SEEK_CUR equ 1
|
||||
SEEK_END equ 2
|
||||
|
@@ -6,6 +6,7 @@ section .rodata
|
||||
;NR_stat equ 4
|
||||
NR_fstat equ 5
|
||||
NR_lstat equ 6
|
||||
NR_lseek equ 8
|
||||
NR_exit equ 60
|
||||
NR_creat equ 85
|
||||
NR_umask equ 95
|
||||
|
66
src/file.asm
66
src/file.asm
@@ -14,6 +14,8 @@ section .text
|
||||
global fclose
|
||||
global fexist
|
||||
global fwrite
|
||||
global fread
|
||||
global fseek
|
||||
|
||||
;----- stat(*file[], *statBuffer[]) -----;
|
||||
; Gets information from a file, stores it into statBuffer[]
|
||||
@@ -217,20 +219,19 @@ fexist:
|
||||
|
||||
;--- fwrite(*filePointer, *data[], ...) -----;
|
||||
; Writes data to given file. Allows format specifiers and variable arguments (see `__INTERNAL_fmt` for supported specifiers)
|
||||
; Return value: Length of given string(data[]), 0 if nothing was written (eg invalid file or file not writable, or data[] is empty)
|
||||
; Return value: Length of given string(data[]), 0 if nothing was written or -errno if an error occured
|
||||
; Used registers:
|
||||
; rax* (ret)
|
||||
; rdi (arg) Pointer to file
|
||||
; rsi (arg) Data to write
|
||||
fwrite:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
cmp rdi, 2
|
||||
jg .cnt
|
||||
xor rax, rax
|
||||
leave
|
||||
mov rax, -EBADF
|
||||
ret
|
||||
.cnt:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
mov rax, rdi
|
||||
mov rdi, rsi
|
||||
mov rsi, rdx
|
||||
@@ -241,3 +242,58 @@ fwrite:
|
||||
call __INTERNAL_fmt
|
||||
leave
|
||||
ret
|
||||
|
||||
;--- fread(*filePointer, *buff[], maxLength) ---;
|
||||
; Reads data from given file.
|
||||
; Return value: Amount of read characters or -errno if an error occured
|
||||
; Used registers:
|
||||
; rax* (ret)
|
||||
; rdi* (arg) Pointer to file
|
||||
; rsi (arg) Pointer to buff[] (where to store read data)
|
||||
; rdx (arg) Size of buff[]
|
||||
fread:
|
||||
cmp rdi, 2
|
||||
jg .cnt
|
||||
mov rax, -EBADF
|
||||
ret
|
||||
.cnt:
|
||||
sub rsp, SIZE_QWORD
|
||||
mov rax, NR_read
|
||||
syscall
|
||||
cmp rax, rdx
|
||||
je .subOne
|
||||
jmp .addAll
|
||||
.subOne:
|
||||
add rsi, rax
|
||||
dec rsi
|
||||
jmp .addEOS
|
||||
.addAll:
|
||||
add rsi, rax
|
||||
.addEOS:
|
||||
mov byte [rsi], EOS
|
||||
.quit:
|
||||
add rsp, SIZE_QWORD
|
||||
ret
|
||||
|
||||
;--- fseek(*filePointer, mode, offset) ---;
|
||||
; Sets pointer in file. Mode is SEEK_SET, SEEK_CUR or SEEK_END.
|
||||
; Return value: On succes returns the resulting offset location as measured in bytes from the beginning of the file. On error, -errno
|
||||
; Used registers:
|
||||
; rax* (ret)
|
||||
; rdi (arg) Pointer to file
|
||||
; rsi (arg) Seek mode
|
||||
; rdx (arg) Pointer offset
|
||||
fseek:
|
||||
cmp rdi, 2
|
||||
jg .cnt
|
||||
mov rax, -EBADF
|
||||
ret
|
||||
.cnt:
|
||||
sub rsp, SIZE_QWORD
|
||||
mov rax, rsi
|
||||
mov rsi, rdx
|
||||
mov rdx, rax
|
||||
mov rax, NR_lseek
|
||||
syscall
|
||||
add rsp, SIZE_QWORD
|
||||
ret
|
||||
|
@@ -96,6 +96,8 @@ extern stat
|
||||
extern lstat
|
||||
extern fgettype
|
||||
extern fgetmod
|
||||
extern fread
|
||||
extern fseek
|
||||
|
||||
section .rodata
|
||||
;;;
|
||||
@@ -136,6 +138,8 @@ section .rodata
|
||||
;file.asm
|
||||
TEST_fopen equ 1 ;Includes fclose
|
||||
TEST_fwrite equ 1
|
||||
TEST_fread equ 1
|
||||
TEST_fseek equ 1
|
||||
TEST_stat equ 1
|
||||
TEST_lstat equ 1
|
||||
TEST_fgettype equ 1
|
||||
@@ -349,6 +353,14 @@ section .rodata
|
||||
addTest(fwrite3, "fwrite(fp1, 'Howdy environment!') //mode 'w'")
|
||||
addTest(fwrite4, "fwrite(fp1, ''%c%c%c%c%c%c%c%c\n'', 'H', 'e', 'l', 'l', 'o', '!', '?', '!')")
|
||||
fwriteStr1 db "%c%c%c%c%c%c%c%c\n",EOS
|
||||
;fread()
|
||||
addTestHeader(_fread, "fread")
|
||||
addTest(fread1, "fread(fp1, strBuff1, 64)")
|
||||
;fseek()
|
||||
addTestHeader(_fseek, "fseek")
|
||||
addTest(fseek1, "fseek(fp1, SEEK_SET, 5)")
|
||||
addTest(fseek2, "fseek(fp1, SEEK_CUR, -1)")
|
||||
addTest(fseek3, "fseek(fp1, SEEK_SET, 0)")
|
||||
;stat()
|
||||
addTestHeader(_stat, "stat")
|
||||
addTest(stat1, "stat('tests', statBuff1)")
|
||||
@@ -1288,6 +1300,91 @@ _start:
|
||||
call fclose
|
||||
%endif
|
||||
|
||||
;--- fread()
|
||||
%if TEST_fread
|
||||
printTestHeader(_fread)
|
||||
mov rdi, [fp1]
|
||||
call fclose
|
||||
lea rdi, [rel file1]
|
||||
mov rsi, 'r'
|
||||
call fopen
|
||||
assert_neq(0)
|
||||
mov [fp1], rax
|
||||
|
||||
printTest(fread1)
|
||||
mov rdi, [fp1]
|
||||
lea rsi, [rel strBuff1]
|
||||
mov rdx, 64
|
||||
call fread
|
||||
assert_more_eq(1)
|
||||
lea rdi, [rel strBuff1]
|
||||
call puts
|
||||
|
||||
mov rdi, [fp1]
|
||||
call fclose
|
||||
%endif
|
||||
|
||||
;--- fseek()
|
||||
%if TEST_fseek
|
||||
%macro fseek_relptr 1
|
||||
%endmacro
|
||||
%macro fseek_readput 0
|
||||
mov rdi, [fp1]
|
||||
lea rsi, [rel strBuff1]
|
||||
mov rdx, 64
|
||||
call fread
|
||||
lea rdi, [rel strBuff1]
|
||||
call puts
|
||||
%endmacro
|
||||
printTestHeader(_fseek)
|
||||
|
||||
lea rdi, [rel file1]
|
||||
mov rsi, 'r'
|
||||
call fopen
|
||||
mov [fp1], rax
|
||||
|
||||
; TEST 1: fseek(fp1, SEEK_SET, 5)
|
||||
printTest(fseek1)
|
||||
mov rdi, [fp1]
|
||||
mov rsi, SEEK_CUR
|
||||
mov rdx, 5
|
||||
call fseek
|
||||
assert_eq(5)
|
||||
fseek_readput
|
||||
|
||||
; TEST 2: fseek(fp1, SEEK_CUR, -1)
|
||||
printTest(fseek2)
|
||||
mov rdi, [fp1]
|
||||
mov rsi, SEEK_SET
|
||||
mov rdx, 5
|
||||
call fseek
|
||||
;^ fseek_readput (fread) modified pointer, so restore it to result of test 1
|
||||
mov rdi, [fp1]
|
||||
mov rsi, SEEK_CUR
|
||||
mov rdx, -1
|
||||
call fseek
|
||||
assert_eq(4)
|
||||
fseek_readput
|
||||
; FAIL. Returned is 26 (which is length of the file)
|
||||
; My best guess is -1 is treated as unsigned. However, according to man 2 lseek:
|
||||
; The off_t data type is a signed integer data type
|
||||
; ( offset in rdx is supposed to be (off_t) offset )
|
||||
; If it turns out unsigned after all, I'll have to manually get current location of pointer (call NR_lseek with SEEK_CUR and offset 0; returned value is current location)
|
||||
; ... and then substract given argument from that
|
||||
|
||||
; TEST 3: fseek(fp1, SEEK_SET, 0)
|
||||
printTest(fseek3)
|
||||
mov rdi, [fp1]
|
||||
mov rsi, SEEK_SET
|
||||
xor rdx, rdx
|
||||
call fseek
|
||||
assert_eq(0)
|
||||
fseek_readput
|
||||
|
||||
mov rdi, [fp1]
|
||||
call fclose
|
||||
%endif
|
||||
|
||||
;--- stat()
|
||||
%if TEST_stat
|
||||
printTestHeader(_stat)
|
||||
|
Reference in New Issue
Block a user