diff --git a/Makefile b/Makefile index 8f69a24..72b0377 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ OBJS := $(DIR_BLD)/tests.o \ $(DIR_BLD)/string.o \ $(DIR_BLD)/convert.o \ $(DIR_BLD)/perror.o \ + $(DIR_BLD)/file.o OBJS_LST := false SRCS := $(patsubst $(DIR_BLD)/%.o,$(SRC_DIR)/%.asm,$(OBJS)) diff --git a/file.asm b/file.asm new file mode 100644 index 0000000..e5c1539 --- /dev/null +++ b/file.asm @@ -0,0 +1,17 @@ +%include "src/constants.asm" + +section .rodata + +section .bss + +section .text + global fexist + +;----- fexist(*file[]) -----; +; Checks if given file exists +; Return value: 1 if file exists, 0 otherwise +; Used registers: +; rax* (ret) +fexist: + xor rax, rax + diff --git a/src/constants.asm b/src/constants.asm index db6763f..d5f70ee 100644 --- a/src/constants.asm +++ b/src/constants.asm @@ -2,7 +2,13 @@ section .rodata ; syscall NR_read equ 0 NR_write equ 1 + NR_open equ 2 + NR_close equ 3 + NR_stat equ 4 + NR_fstat equ 5 + NR_lstat equ 6 NR_exit equ 60 + NR_umask equ 95 ; file descriptors FD_stdin equ 0 diff --git a/src/core.asm b/src/core.asm index 6478ecb..bab4939 100644 --- a/src/core.asm +++ b/src/core.asm @@ -12,6 +12,8 @@ section .text global maxu global clamp global clampu + global umask_set + global umask_get ;----- exit(exit_code) -----; ; Exits the program with given exit code @@ -177,3 +179,30 @@ clampu: cmova rax, rdx .quit: ret + +;----- umask_set(umask) -----; +; Sets umask +; Return value: Return value of syscall sys_umask +; Used registers: +; rax* syscall >> (ret) +; rdi umask to set +umask_set: + mov rax, NR_umask + syscall + ret + +;----- umask_get() -----; +; Gets umask +; Return value: Current umask +; Used registers: +; rax* syscall >> (ret) current umask +; rdi* syscall arg +; rdx* Stores umask for restoring+returning umask +umask_get: + xor rdi, rdi + call umask_set + mov rdx, rax + mov rdi, rax + call umask_set + mov rax, rdx + ret diff --git a/src/file.asm b/src/file.asm new file mode 100644 index 0000000..0f4bbe9 --- /dev/null +++ b/src/file.asm @@ -0,0 +1,99 @@ +%include "src/constants.asm" + +extern umask_get + +section .rodata + ; Open flags + O_ACCMODE equ 00000003 + O_RDONLY equ 00000000 + O_WRONLY equ 00000001 + O_RDWR equ 00000002 + O_CREAT equ 00000100 ;create if not exist + O_EXCL equ 00000200 ;fail if file exists and O_EXCL+O_CREAT set + O_NOCTTY equ 00000400 + O_TRUNC equ 00001000 + O_APPEND equ 00002000 + O_NONBLOCK equ 00004000 + O_DSYNC equ 00010000 + FASYNC equ 00020000 + O_DIRECT equ 00040000 + O_LARGEFILE equ 00100000 + O_DIRECTORY equ 00200000 + O_NOFOLLOW equ 00400000 + O_NOATIME equ 01000000 + O_CLOEXEC equ 02000000 + __O_SYNC equ 04000000 + O_SYNC equ (__O_SYNC | O_DSYNC) + O_PATH equ 01000000 + __O_TMPFILE equ 02000000 + O_TMPFILE equ (__O_TMPFILE | O_DIRECTORY) + O_NDELAY equ O_NONBLOCK + ; Permission flags + S_IXOTH equ 00001 ;o=x + S_IWOTH equ 00002 ;o=w + S_IROTH equ 00004 ;o=r + S_IRWXO equ 00007 ;o=rwx + S_IXGRP equ 00010 ;g=x + S_IWGRP equ 00020 ;g=w + S_IRGRP equ 00040 ;g=r + S_IRWXG equ 00070 ;g=rwx + S_IXUSR equ 00100 ;u=x + S_IWUSR equ 00200 ;u=w + S_IRUSR equ 00400 ;u=r + S_IRWXU equ 00700 ;u=rwx + S_ISVIX equ 0001000 ;sticky bit + S_ISGID equ 0002000 ;set-group-ID bit + S_ISUID equ 0004000 ;set-user-ID bit + +section .bss + +section .text + global fopen + global fclose + global fexist + +;----- fopen(*file[], char mode) -----; +; Opens a file +; Return value: Pointer to opened file pointer, 0 (EOS) otherwise. +; Possible modes: +; 'r' Read-only, file must exist +; 'w' Write-only. Creates empty file or truncates an existing file +; 'a' Append. Creates file if it does not exist +; 'R' Read+write, file must exist +; 'W' Read+write. Creates empty file or truncates an existing file +; 'A' Read+append. Creates file if it does not exist +; Invalid mode will also return 0 (EOS) +; Used registers: +; rax* (ret) +; rdi (arg) Pointer to string holding (path+)file name +; rsi Mode to open the file with (see description above) +fopen: + ret + +;----- fclose(file) -----; +; Closes an opened file +; Return value: 0 if file closed. Negative error number if an error occured +; Used registers: +; rax* (ret) +; rdi (arg) Pointer to opened file +fclose: + cmp rdi, 3 + jl .invalid_fd ;disallow closing stdin,stdout,stderr + mov rax, NR_close + syscall + jmp .quit + + .invalid_fd: + mov rax, -EINVAL + + .quit: + ret + +;----- fexist(*file[]) -----; +; Checks if given file exists (attempts to open the file) +; Return value: 0- File closed succesfully. -errno (negative error number) if an error occured +; Used registers: +; rax* (ret) +; rdi (arg) Pointer to string holding (path+)file name +fexist: + ret diff --git a/test b/test new file mode 100644 index 0000000..e69de29