Adds lstat()

This commit is contained in:
2025-07-27 16:25:23 +02:00
parent 0c5bbde4a4
commit c40a59b4ff
3 changed files with 214 additions and 101 deletions

View File

@@ -1,73 +1,75 @@
section .rodata section .rodata
; Open flags ; Open flags
O_ACCMODE equ 00000003q O_ACCMODE equ 00000003q
O_RDONLY equ 00000000q O_RDONLY equ 00000000q
O_WRONLY equ 00000001q O_WRONLY equ 00000001q
O_RDWR equ 00000002q O_RDWR equ 00000002q
O_CREAT equ 00000100q ;create if not exist O_CREAT equ 00000100q ;create if not exist
O_EXCL equ 00000200q ;fail if file exists and O_EXCL+O_CREAT set O_EXCL equ 00000200q ;fail if file exists and O_EXCL+O_CREAT set
O_NOCTTY equ 00000400q O_NOCTTY equ 00000400q
O_TRUNC equ 00001000q O_TRUNC equ 00001000q
O_APPEND equ 00002000q O_APPEND equ 00002000q
O_NONBLOCK equ 00004000q O_NONBLOCK equ 00004000q
O_DSYNC equ 00010000q O_DSYNC equ 00010000q
FASYNC equ 00020000q FASYNC equ 00020000q
O_DIRECT equ 00040000q O_DIRECT equ 00040000q
O_LARGEFILE equ 00100000q O_LARGEFILE equ 00100000q
O_DIRECTORY equ 00200000q O_DIRECTORY equ 00200000q
O_NOFOLLOW equ 00400000q O_NOFOLLOW equ 00400000q
O_NOATIME equ 01000000q O_NOATIME equ 01000000q
O_CLOEXEC equ 02000000q O_CLOEXEC equ 02000000q
__O_SYNC equ 04000000q __O_SYNC equ 04000000q
O_SYNC equ (__O_SYNC | O_DSYNC) O_SYNC equ (__O_SYNC | O_DSYNC)
O_PATH equ 01000000q O_PATH equ 01000000q
__O_TMPFILE equ 02000000q __O_TMPFILE equ 02000000q
O_TMPFILE equ (__O_TMPFILE | O_DIRECTORY) O_TMPFILE equ (__O_TMPFILE | O_DIRECTORY)
O_NDELAY equ O_NONBLOCK O_NDELAY equ O_NONBLOCK
; Permission flags ; Permission flags
S_IXOTH equ 00001q ;o=x S_IXOTH equ 00001q ;o=x
S_IWOTH equ 00002q ;o=w S_IWOTH equ 00002q ;o=w
S_IROTH equ 00004q ;o=r S_IROTH equ 00004q ;o=r
S_IRWXO equ 00007q ;o=rwx S_IRWXO equ 00007q ;o=rwx
S_IXGRP equ 00010q ;g=x S_IXGRP equ 00010q ;g=x
S_IWGRP equ 00020q ;g=w S_IWGRP equ 00020q ;g=w
S_IRGRP equ 00040q ;g=r S_IRGRP equ 00040q ;g=r
S_IRWXG equ 00070q ;g=rwx S_IRWXG equ 00070q ;g=rwx
S_IXUSR equ 00100q ;u=x S_IXUSR equ 00100q ;u=x
S_IWUSR equ 00200q ;u=w S_IWUSR equ 00200q ;u=w
S_IRUSR equ 00400q ;u=r S_IRUSR equ 00400q ;u=r
S_IRWXU equ 00700q ;u=rwx S_IRWXU equ 00700q ;u=rwx
S_ISVTX equ 0001000q ;sticky bit S_ISVTX equ 0001000q ;sticky bit
S_ISGID equ 0002000q ;set-group-ID bit S_ISGID equ 0002000q ;set-group-ID bit
S_ISUID equ 0004000q ;set-user-ID bit S_ISUID equ 0004000q ;set-user-ID bit
; Stat buffer fields ; Stat buffer fields
ST_DEV equ 0 ; Device unsigned ST_DEV equ 0 ; Device unsigned
ST_INO equ 8 ; File serial number unsigned ST_INO equ 8 ; File serial number unsigned
ST_NLINK equ 16 ; Number of links unsigned ST_NLINK equ 16 ; Number of links unsigned
ST_MODE equ 24 ; File mode unsigned, 4 bytes ST_MODE equ 24 ; File mode unsigned, 4 bytes
ST_UID equ 28 ; User ID of the file's owner unsigned, 4 bytes ST_UID equ 28 ; User ID of the file's owner unsigned, 4 bytes
ST_GID equ 32 ; Group ID of the file's group unsigned, 4 bytes ST_GID equ 32 ; Group ID of the file's group unsigned, 4 bytes
ST__PAD0 equ 36 ST__PAD0 equ 36
ST_RDEV equ 40 ; Device number, if device unsigned ST_RDEV equ 40 ; Device number, if device unsigned
ST_SIZE equ 48 ; Size of file, in bytes signed ST_SIZE equ 48 ; Size of file, in bytes signed
ST_BLKSIZE equ 56 ; Optimal block size for I/O signed ST_BLKSIZE equ 56 ; Optimal block size for I/O signed
ST_BLOCKS equ 64 ; Number 512-byte blocks allocated signed ST_BLOCKS equ 64 ; Number 512-byte blocks allocated signed
ST_ATIME equ 72 ; Time of last access unsigned ST_ATIME equ 72 ; Time of last access unsigned
ST_ATIME_NSEC equ 80 ; unsigned ST_ATIME_NSEC equ 80 ; unsigned
ST_MTIME equ 88 ; Time of last modification unsigned ST_MTIME equ 88 ; Time of last modification unsigned
ST_MTIME_NSEC equ 96 ; unsigned ST_MTIME_NSEC equ 96 ; unsigned
ST_CTIME equ 104 ; Time of last status change unsigned ST_CTIME equ 104 ; Time of last status change unsigned
ST_CTIME_NSEC equ 112 ; unsigned ST_CTIME_NSEC equ 112 ; unsigned
ST__UNUSED equ 120 ST__UNUSED equ 120
ST__END equ 128 ; End of stat buffer ST__END equ 128 ; End of stat buffer
STATBUFF_SIZE equ ST__END STATBUFF_SIZE equ ST__END
AT_FDCWD equ -100 AT_FDCWD equ -100
AT_SYMLINK_NOFOLLOW equ 0x100
AT_SYMLINK_FOLLOW equ 0x400
; File types ; File types
S_IFDIR equ 0040000q ; Directory S_IFDIR equ 0040000q ; Directory
S_IFCHR equ 0020000q ; Character device S_IFCHR equ 0020000q ; Character device
S_IFBLK equ 0060000q ; Block device S_IFBLK equ 0060000q ; Block device
S_IFREG equ 0100000q ; Regular file S_IFREG equ 0100000q ; Regular file
S_IFIFO equ 0010000q ; FIFO S_IFIFO equ 0010000q ; FIFO
S_IFLNK equ 0120000q ; Symbolic link S_IFLNK equ 0120000q ; Symbolic link
S_IFSOCK equ 0140000q ; Socket S_IFSOCK equ 0140000q ; Socket

View File

@@ -7,6 +7,7 @@ extern umask_get
section .text section .text
global stat global stat
global lstat
global fgettype global fgettype
global fgetmod global fgetmod
global fopen global fopen
@@ -34,6 +35,19 @@ stat:
add rsp, SIZE_QWORD add rsp, SIZE_QWORD
ret ret
;----- lstat(*file[], *statBuffer[]) -----;
; Same as stat, except do not follow links
lstat:
sub rsp, SIZE_QWORD
mov rax, NR_newfstatat
mov rdx, rsi
mov rsi, rdi
mov rdi, AT_FDCWD
mov r10, AT_SYMLINK_NOFOLLOW
syscall
add rsp, SIZE_QWORD
ret
;----- fgettype(*statBuffer[]) -----; ;----- fgettype(*statBuffer[]) -----;
; Gets file type from stat buffer ; Gets file type from stat buffer
; Return value: Permissions of given file or -EINVAL if statBuffer is invalid (first bit is 0) ; Return value: Permissions of given file or -EINVAL if statBuffer is invalid (first bit is 0)

View File

@@ -93,6 +93,7 @@ extern fclose
extern fexist extern fexist
extern fwrite extern fwrite
extern stat extern stat
extern lstat
extern fgettype extern fgettype
extern fgetmod extern fgetmod
@@ -136,6 +137,7 @@ section .rodata
TEST_fopen equ 1 ;Includes fclose TEST_fopen equ 1 ;Includes fclose
TEST_fwrite equ 1 TEST_fwrite equ 1
TEST_stat equ 1 TEST_stat equ 1
TEST_lstat equ 1
TEST_fgettype equ 1 TEST_fgettype equ 1
TEST_fgetmod equ 1 TEST_fgetmod equ 1
@@ -349,7 +351,8 @@ section .rodata
fwriteStr1 db "%c%c%c%c%c%c%c%c\n",EOS fwriteStr1 db "%c%c%c%c%c%c%c%c\n",EOS
;stat() ;stat()
addTestHeader(_stat, "stat") addTestHeader(_stat, "stat")
addTest(stat1, "stat(file1)") addTest(stat1, "stat('tests', statBuff1)")
bin_file db "tests",EOS
statStr db "\t## Stats of file: %s ##\n" statStr db "\t## Stats of file: %s ##\n"
db "\tDevice: %u\n" db "\tDevice: %u\n"
db "\tInode: %u\n" db "\tInode: %u\n"
@@ -364,9 +367,13 @@ section .rodata
db "\tatime: %u.%u\n" db "\tatime: %u.%u\n"
db "\tmtime: %u.%u\n" db "\tmtime: %u.%u\n"
db "\tctime: %u.%u\n",EOS db "\tctime: %u.%u\n",EOS
;lstat()
addTestHeader(_lstat, "lstat")
addTest(lstat1, "lstat('test', statBuff2)")
;fgettype() ;fgettype()
addTestHeader(_fgettype, "fgettype") addTestHeader(_fgettype, "fgettype")
addTest(fgettype1, "fgettype(statBuffer)") addTest(fgettype1, "fgettype(statBuff1)")
addTest(fgettype2, "fgettype(statBuff2)")
fgettypeStr db "\t- '%s' is filetype: %s\n",EOS fgettypeStr db "\t- '%s' is filetype: %s\n",EOS
ftype_dir db "Directory",EOS ftype_dir db "Directory",EOS
ftype_char db "Character Device",EOS ftype_char db "Character Device",EOS
@@ -378,14 +385,16 @@ section .rodata
ftype_unknown db "Unknown (function fgettype() or stat() failed succesfully)",EOS ftype_unknown db "Unknown (function fgettype() or stat() failed succesfully)",EOS
;fgetmod() ;fgetmod()
addTestHeader(_fgetmod, "fgetmod") addTestHeader(_fgetmod, "fgetmod")
addTest(fgetmod1, "fgetmod(statBuffer)") addTest(fgetmod1, "fgetmod(statBuff1)")
addTest(fgetmod2, "fgetmod(statbuff2)")
fgetmodStr db "\t- File permissions of file '%s': %04o\n",EOS fgetmodStr db "\t- File permissions of file '%s': %04o\n",EOS
section .bss section .bss
strBuff1 resb 64 strBuff1 resb 64
strBuff2 resb 64 strBuff2 resb 64
fp1 resq 1 fp1 resq 1
statBuff resb STATBUFF_SIZE statBuff1 resb STATBUFF_SIZE
statBuff2 resb STATBUFF_SIZE
section .text section .text
global _start global _start
@@ -1284,30 +1293,64 @@ _start:
printTestHeader(_stat) printTestHeader(_stat)
printTest(stat1) printTest(stat1)
lea rdi, [rel file1] lea rdi, [rel bin_file]
lea rsi, [rel statBuff] lea rsi, [rel statBuff1]
call stat call stat
assert_eq(0) assert_eq(0)
lea rdi, [rel statStr] lea rdi, [rel statStr]
lea rsi, [rel file1] lea rsi, [rel bin_file]
mov rdx, [statBuff + ST_DEV] mov rdx, [statBuff1 + ST_DEV]
mov rcx, [statBuff + ST_INO] mov rcx, [statBuff1 + ST_INO]
mov r8, [statBuff + ST_NLINK] mov r8, [statBuff1 + ST_NLINK]
mov r9d, [statBuff + ST_MODE] mov r9d, [statBuff1 + ST_MODE]
push qword [statBuff + ST_CTIME_NSEC] push qword [statBuff1 + ST_CTIME_NSEC]
push qword [statBuff + ST_CTIME] push qword [statBuff1 + ST_CTIME]
push qword [statBuff + ST_MTIME_NSEC] push qword [statBuff1 + ST_MTIME_NSEC]
push qword [statBuff + ST_MTIME] push qword [statBuff1 + ST_MTIME]
push qword [statBuff + ST_ATIME_NSEC] push qword [statBuff1 + ST_ATIME_NSEC]
push qword [statBuff + ST_ATIME] push qword [statBuff1 + ST_ATIME]
push qword [statBuff + ST_BLOCKS] push qword [statBuff1 + ST_BLOCKS]
push qword [statBuff + ST_BLKSIZE] push qword [statBuff1 + ST_BLKSIZE]
push qword [statBuff + ST_SIZE] push qword [statBuff1 + ST_SIZE]
push qword [statBuff + ST_RDEV] push qword [statBuff1 + ST_RDEV]
mov r10d, [statBuff + ST_GID] mov r10d, [statBuff1 + ST_GID]
push r10 push r10
mov r10d, [statBuff + ST_UID] mov r10d, [statBuff1 + ST_UID]
push r10
call printf
add rsp, SIZE_QWORD * 12
%endif
;--- lstat()
%if TEST_lstat
printTestHeader(_lstat)
printTest(lstat1)
lea rdi, [rel bin_file]
lea rsi, [rel statBuff2]
call lstat
assert_eq(0)
lea rdi, [rel statStr]
lea rsi, [rel bin_file]
mov rdx, [statBuff2 + ST_DEV]
mov rcx, [statBuff2 + ST_INO]
mov r8, [statBuff2 + ST_NLINK]
mov r9d, [statBuff2 + ST_MODE]
push qword [statBuff2 + ST_CTIME_NSEC]
push qword [statBuff2 + ST_CTIME]
push qword [statBuff2 + ST_MTIME_NSEC]
push qword [statBuff2 + ST_MTIME]
push qword [statBuff2 + ST_ATIME_NSEC]
push qword [statBuff2 + ST_ATIME]
push qword [statBuff2 + ST_BLOCKS]
push qword [statBuff2 + ST_BLKSIZE]
push qword [statBuff2 + ST_SIZE]
push qword [statBuff2 + ST_RDEV]
mov r10d, [statBuff2 + ST_GID]
push r10
mov r10d, [statBuff2 + ST_UID]
push r10 push r10
call printf call printf
add rsp, SIZE_QWORD * 12 add rsp, SIZE_QWORD * 12
@@ -1317,8 +1360,9 @@ _start:
%if TEST_fgettype %if TEST_fgettype
printTestHeader(_fgettype) printTestHeader(_fgettype)
; TEST 1: fgettype(statBuff1)
printTest(fgettype1) printTest(fgettype1)
lea rdi, [rel statBuff] lea rdi, [rel statBuff1]
call fgettype call fgettype
assert_neq(-EINVAL) assert_neq(-EINVAL)
@@ -1326,49 +1370,102 @@ _start:
lea rsi, [rel ftype_dir] lea rsi, [rel ftype_dir]
cmp rax, S_IFDIR cmp rax, S_IFDIR
cmove rdx, rsi cmove rdx, rsi
je .fgettype_cnt je .fgettype1cnt
lea rsi, [rel ftype_char] lea rsi, [rel ftype_char]
cmp rax, S_IFCHR cmp rax, S_IFCHR
cmove rdx, rsi cmove rdx, rsi
je .fgettype_cnt je .fgettype1cnt
lea rsi, [rel ftype_blk] lea rsi, [rel ftype_blk]
cmp rax, S_IFBLK cmp rax, S_IFBLK
cmove rdx, rsi cmove rdx, rsi
je .fgettype_cnt je .fgettype1cnt
lea rsi, [rel ftype_reg] lea rsi, [rel ftype_reg]
cmp rax, S_IFREG cmp rax, S_IFREG
cmove rdx, rsi cmove rdx, rsi
je .fgettype_cnt je .fgettype1cnt
lea rsi, [rel ftype_fifo] lea rsi, [rel ftype_fifo]
cmp rax, S_IFIFO cmp rax, S_IFIFO
cmove rdx, rsi cmove rdx, rsi
je .fgettype_cnt je .fgettype1cnt
lea rsi, [rel ftype_link] lea rsi, [rel ftype_link]
cmp rax, S_IFLNK cmp rax, S_IFLNK
cmove rdx, rsi cmove rdx, rsi
je .fgettype_cnt je .fgettype1cnt
lea rsi, [rel ftype_sock] lea rsi, [rel ftype_sock]
cmp rax, S_IFSOCK cmp rax, S_IFSOCK
cmove rdx, rsi cmove rdx, rsi
.fgettype_cnt: .fgettype1cnt:
lea rdi, [rel fgettypeStr] lea rdi, [rel fgettypeStr]
lea rsi, [rel file1] lea rsi, [rel bin_file]
call printf call printf
; TEST 2: fgettype(statBuff2)
printTest(fgettype2)
lea rdi, [rel statBuff2]
call fgettype
assert_neq(-EINVAL)
lea rdx, [rel ftype_unknown]
lea rsi, [rel ftype_dir]
cmp rax, S_IFDIR
cmove rdx, rsi
je .fgettype2cnt
lea rsi, [rel ftype_char]
cmp rax, S_IFCHR
cmove rdx, rsi
je .fgettype2cnt
lea rsi, [rel ftype_blk]
cmp rax, S_IFBLK
cmove rdx, rsi
je .fgettype2cnt
lea rsi, [rel ftype_reg]
cmp rax, S_IFREG
cmove rdx, rsi
je .fgettype2cnt
lea rsi, [rel ftype_fifo]
cmp rax, S_IFIFO
cmove rdx, rsi
je .fgettype2cnt
lea rsi, [rel ftype_link]
cmp rax, S_IFLNK
cmove rdx, rsi
je .fgettype2cnt
lea rsi, [rel ftype_sock]
cmp rax, S_IFSOCK
cmove rdx, rsi
.fgettype2cnt:
lea rdi, [rel fgettypeStr]
lea rsi, [rel bin_file]
call printf
%endif %endif
;--- fgetmod() ;--- fgetmod()
%if TEST_fgetmod %if TEST_fgetmod
printTestHeader(_fgetmod) printTestHeader(_fgetmod)
; TEST 1: fgetmod(statBuff1)
printTest(fgetmod1) printTest(fgetmod1)
lea rdi, [rel statBuff] lea rdi, [rel statBuff1]
call fgetmod call fgetmod
assert_neq(-EINVAL) assert_neq(-EINVAL)
lea rdi, [rel fgetmodStr] lea rdi, [rel fgetmodStr]
lea rsi, [rel file1] lea rsi, [rel bin_file]
mov rdx, rax mov rdx, rax
call printf call printf
; TEST 2: fgetmod(statBuff2)
printTest(fgetmod2)
lea rdi, [rel statBuff2]
call fgetmod
assert_neq(-EINVAL)
lea rdi, [rel fgetmodStr]
lea rsi, [rel bin_file]
mov rdx, rax
call printf
%endif %endif
;;; ;;;