summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-24 14:10:07 +0200
committerAnton Kling <anton@kling.gg>2023-10-24 14:10:07 +0200
commit2292b11e82a3d6d70e7bb932c512155dc13c5025 (patch)
treeda7d90e778495bc9a67ee0e09b32813c11dc6fe5
parente93a49d1eadf4a4b36369e67f112f8c45a0d567e (diff)
VFS/LibC: Create ftruncate function and corresponding syscall and libc implementation
Previously this function was only used for shared memory region created by shm_open because I was lazy. Now exists for all files.
-rw-r--r--Makefile2
-rw-r--r--cpu/syscall.c1
-rw-r--r--fs/ext2.c4
-rw-r--r--fs/shm.c40
-rw-r--r--fs/tmpfs.c5
-rw-r--r--fs/vfs.c19
-rw-r--r--fs/vfs.h5
-rw-r--r--scalls/shm.c4
-rw-r--r--scalls/shm.h6
-rw-r--r--socket.c2
-rw-r--r--userland/libc/Makefile2
-rw-r--r--userland/libc/include/unistd.h2
-rw-r--r--userland/libc/libc.c5
-rw-r--r--userland/libc/unistd/ftruncate.c6
14 files changed, 56 insertions, 47 deletions
diff --git a/Makefile b/Makefile
index 32b521f..1a77824 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
CC="./sysroot/bin/i686-sb-gcc"
AS="./sysroot/bin/i686-sb-as"
-OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o scalls/mkdir.o
+OBJ = arch/i386/boot.o init/kernel.o cpu/gdt.o cpu/reload_gdt.o cpu/idt.o cpu/io.o libc/stdio/print.o drivers/keyboard.o log.o drivers/pit.o libc/string/memcpy.o libc/string/strlen.o libc/string/memcmp.o drivers/ata.o libc/string/memset.o cpu/syscall.o read_eip.o libc/exit/assert.o process.o cpu/int_syscall.o libc/string/strcpy.o arch/i386/mmu.o kmalloc.o fs/ext2.o fs/vfs.o fs/devfs.o cpu/spinlock.o random.o libc/string/strcmp.o crypto/ChaCha20/chacha20.o crypto/SHA1/sha1.o fs/tmpfs.o libc/string/isequal.o drivers/pst.o halts.o scalls/ppoll.o scalls/ftruncate.o kubsan.o scalls/mmap.o drivers/serial.o scalls/accept.o scalls/bind.o scalls/socket.o socket.o poll.o fs/fifo.o hashmap/hashmap.o fs/shm.o scalls/shm.o elf.o ksbrk.o sched/scheduler.o scalls/stat.o libc/string/copy.o libc/string/strncpy.o drivers/mouse.o libc/string/strlcpy.o libc/string/strcat.o drivers/vbe.o scalls/msleep.o scalls/uptime.o scalls/mkdir.o
CFLAGS = -O2 -fsanitize=vla-bound,shift-exponent,pointer-overflow,shift,signed-integer-overflow,bounds -ggdb -ffreestanding -Wall -Werror -mgeneral-regs-only -Wimplicit-fallthrough -I./libc/include/ -I.
INCLUDE=-I./includes/ -I./libc/include/
diff --git a/cpu/syscall.c b/cpu/syscall.c
index 4682c53..c072053 100644
--- a/cpu/syscall.c
+++ b/cpu/syscall.c
@@ -13,6 +13,7 @@
#include <scalls/msleep.h>
#include <scalls/ppoll.h>
#include <scalls/shm.h>
+#include <scalls/ftruncate.h>
#include <scalls/socket.h>
#include <scalls/stat.h>
#include <scalls/uptime.h>
diff --git a/fs/ext2.c b/fs/ext2.c
index 98ef2c7..14bcfcb 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -505,7 +505,7 @@ vfs_inode_t *ext2_open(const char *path) {
1 /*is_open*/, NULL /*internal_object*/, file_size,
ext2_open, ext2_create_file, ext2_read, ext2_write,
ext2_close, ext2_create_directory,
- NULL /*get_vm_object*/);
+ NULL /*get_vm_object*/, NULL/*truncate*/);
}
uint64_t end_of_last_entry_position(int dir_inode, uint64_t *entry_offset,
@@ -697,7 +697,7 @@ vfs_inode_t *ext2_mount(void) {
0 /*can_write*/, 0 /*is_open*/,
NULL /*internal_object*/, 0 /*file_size*/, ext2_open,
ext2_create_file, ext2_read, ext2_write, ext2_close,
- ext2_create_directory, NULL /*get_vm_object*/);
+ ext2_create_directory, NULL /*get_vm_object*/, NULL/*truncate*/);
}
void parse_superblock(void) {
diff --git a/fs/shm.c b/fs/shm.c
index 8668c9a..4d5f2ab 100644
--- a/fs/shm.c
+++ b/fs/shm.c
@@ -47,6 +47,19 @@ vfs_vm_object_t *shm_get_vm_object(uint64_t length, uint64_t offset,
return p;
}
+int shm_ftruncate(vfs_fd_t *fd, size_t length) {
+ vfs_vm_object_t *p = fd->inode->internal_object;
+ p->size = length;
+ p->virtual_object = ksbrk(length);
+ int n = (uintptr_t)align_page((void *)(uint32_t)length) / 0x1000;
+ p->object = kmalloc(sizeof(void *) * n);
+ for (int i = 0; i < n; i++)
+ p->object[i] =
+ (void *)(get_page(p->virtual_object + (i * 0x1000), NULL, 0, 0)->frame *
+ 0x1000);
+ return 0;
+}
+
int shm_open(const char *name, int oflag, mode_t mode) {
// Try to find or create a new shared memory object.
vfs_vm_object_t *internal_object =
@@ -60,11 +73,11 @@ int shm_open(const char *name, int oflag, mode_t mode) {
hashmap_add_entry(shared_memory_objects, name, internal_object, NULL, 0);
}
- vfs_inode_t *inode =
- vfs_create_inode(0 /*inode_num*/, 0 /*type*/, 1 /*has_data*/,
- 1 /*can_write*/, 1 /*is_open*/, internal_object,
- 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/,
- shm_read, shm_write, NULL /*close*/, NULL/*create_directory*/, shm_get_vm_object);
+ vfs_inode_t *inode = vfs_create_inode(
+ 0 /*inode_num*/, 0 /*type*/, 1 /*has_data*/, 1 /*can_write*/,
+ 1 /*is_open*/, internal_object, 0 /*file_size*/, NULL /*open*/,
+ NULL /*create_file*/, shm_read, shm_write, NULL /*close*/,
+ NULL /*create_directory*/, shm_get_vm_object, shm_ftruncate);
vfs_fd_t *fd_ptr;
int fd = vfs_create_fd(oflag, mode, inode, &fd_ptr);
@@ -79,20 +92,3 @@ int shm_unlink(const char *name) {
(void)name;
return 0;
}
-
-int ftruncate(int fildes, uint64_t length) {
- kprintf("ftruncate: %d\n", length);
- vfs_fd_t *fd = get_current_task()->file_descriptors[fildes];
- if (!fd)
- return -EBADF;
- vfs_vm_object_t *p = fd->inode->internal_object;
- p->size = length;
- p->virtual_object = ksbrk(length);
- int n = (uintptr_t)align_page((void *)(uint32_t)length) / 0x1000;
- p->object = kmalloc(sizeof(void *) * n);
- for (int i = 0; i < n; i++)
- p->object[i] =
- (void *)(get_page(p->virtual_object + (i * 0x1000), NULL, 0, 0)->frame *
- 0x1000);
- return 0;
-}
diff --git a/fs/tmpfs.c b/fs/tmpfs.c
index 575ab0c..a9a3c1f 100644
--- a/fs/tmpfs.c
+++ b/fs/tmpfs.c
@@ -48,7 +48,7 @@ void dual_pipe(int fd[2]) {
0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open,
internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/,
tmp_read, tmp_write, tmp_close, NULL /*create_directory*/,
- NULL /*get_vm_object*/);
+ NULL /*get_vm_object*/, NULL /*truncate*/);
assert(inode);
vfs_fd_t *fd_ptr;
@@ -77,7 +77,8 @@ void pipe(int fd[2]) {
vfs_inode_t *inode = vfs_create_inode(
0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open,
internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/,
- tmp_read, tmp_write, tmp_close, NULL/*create_directory*/, NULL /*get_vm_object*/);
+ tmp_read, tmp_write, tmp_close, NULL /*create_directory*/,
+ NULL /*get_vm_object*/, NULL/*truncate*/);
assert(inode);
vfs_fd_t *fd_ptr;
diff --git a/fs/vfs.c b/fs/vfs.c
index 5f61d89..0c616a2 100644
--- a/fs/vfs.c
+++ b/fs/vfs.c
@@ -32,7 +32,8 @@ vfs_inode_t *vfs_create_inode(
void (*close)(vfs_fd_t *fd),
int (*create_directory)(const char *path, int mode),
vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset,
- vfs_fd_t *fd)) {
+ vfs_fd_t *fd),
+ int (*truncate)(vfs_fd_t *fd, size_t length)) {
vfs_inode_t *r = kmalloc(sizeof(inode_t));
r->inode_num = inode_num;
r->type = type;
@@ -48,6 +49,7 @@ vfs_inode_t *vfs_create_inode(
r->close = close;
r->create_directory = create_directory;
r->get_vm_object = get_vm_object;
+ r->truncate = truncate;
return r;
}
@@ -291,6 +293,21 @@ int vfs_dup2(int org_fd, int new_fd) {
return 1;
}
+int vfs_ftruncate(int fd, size_t length) {
+ vfs_fd_t *fd_ptr = get_vfs_fd(fd);
+ if (!fd_ptr)
+ return -EBADF;
+ if (!(fd_ptr->flags & O_READ))
+ return -EINVAL;
+ vfs_inode_t *inode = fd_ptr->inode;
+ if (!inode)
+ return -EINVAL;
+ if (!inode->truncate)
+ return -EINVAL;
+
+ return inode->truncate(fd_ptr, length);
+}
+
void vfs_mount(char *path, vfs_inode_t *local_root) {
int len = strlen(path);
mounts[num_mounts].path = kmalloc_eternal(len + 1);
diff --git a/fs/vfs.h b/fs/vfs.h
index b8a9984..f8a4b19 100644
--- a/fs/vfs.h
+++ b/fs/vfs.h
@@ -68,6 +68,7 @@ struct vfs_inode {
int (*create_directory)(const char *path, int mode);
vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset,
vfs_fd_t *fd);
+ int (*truncate)(vfs_fd_t *fd, size_t length);
};
int vfs_close(int fd);
@@ -83,6 +84,7 @@ int vfs_dup2(int org_fd, int new_fd);
vfs_inode_t *vfs_internal_open(const char *file);
int vfs_mkdir(const char *path, int mode);
int vfs_create_fd(int flags, int mode, vfs_inode_t *inode, vfs_fd_t **fd);
+int vfs_ftruncate(int fd, size_t length);
vfs_inode_t *vfs_create_inode(
int inode_num, int type, uint8_t has_data, uint8_t can_write,
uint8_t is_open, void *internal_object, uint64_t file_size,
@@ -93,5 +95,6 @@ vfs_inode_t *vfs_create_inode(
void (*close)(vfs_fd_t *fd),
int (*create_directory)(const char *path, int mode),
vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset,
- vfs_fd_t *fd));
+ vfs_fd_t *fd),
+ int (*truncate)(vfs_fd_t *fd, size_t length));
#endif
diff --git a/scalls/shm.c b/scalls/shm.c
index 2e8924f..979084a 100644
--- a/scalls/shm.c
+++ b/scalls/shm.c
@@ -4,7 +4,3 @@
int syscall_shm_open(SYS_SHM_OPEN_PARAMS *args) {
return shm_open(args->name, args->oflag, args->mode);
}
-
-int syscall_ftruncate(SYS_FTRUNCATE_PARAMS *args) {
- return ftruncate(args->fildes, args->length);
-}
diff --git a/scalls/shm.h b/scalls/shm.h
index 6d4e13e..80e4366 100644
--- a/scalls/shm.h
+++ b/scalls/shm.h
@@ -10,11 +10,5 @@ typedef struct SYS_SHM_OPEN_PARAMS {
mode_t mode;
} __attribute__((packed)) SYS_SHM_OPEN_PARAMS;
-typedef struct SYS_FTRUNCATE_PARAMS {
- int fildes;
- uint64_t length;
-} __attribute__((packed)) SYS_FTRUNCATE_PARAMS;
-
int syscall_shm_open(SYS_SHM_OPEN_PARAMS *args);
-int syscall_ftruncate(SYS_FTRUNCATE_PARAMS *args);
#endif
diff --git a/socket.c b/socket.c
index 8328b38..59f86bf 100644
--- a/socket.c
+++ b/socket.c
@@ -128,7 +128,7 @@ int socket(int domain, int type, int protocol) {
0 /*inode_num*/, FS_TYPE_UNIX_SOCKET, 0 /*has_data*/, 1 /*can_write*/,
1 /*is_open*/, new_socket /*internal_object*/, 0 /*file_size*/,
NULL /*open*/, NULL /*create_file*/, socket_read, socket_write,
- socket_close, NULL/*create_directory*/, NULL /*get_vm_object*/);
+ socket_close, NULL/*create_directory*/, NULL /*get_vm_object*/, NULL/*truncate*/);
vfs_fd_t *fd;
int n = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, inode, &fd);
diff --git a/userland/libc/Makefile b/userland/libc/Makefile
index 0681eda..704bf79 100644
--- a/userland/libc/Makefile
+++ b/userland/libc/Makefile
@@ -2,7 +2,7 @@ CC="i686-sb-gcc"
AR="i686-sb-ar"
AS="i686-sb-as"
CFLAGS = -ggdb -ffreestanding -O2 -Wall -pedantic -Wimplicit-fallthrough -I./include/ -static
-OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o libgen/basename.o string/strdup.o string/strndup.o string/strlcpy.o stdlib/atexit.o stdio/open_memstream.o libgen/dirname.o unistd/unlink.o string/strstr.o string/strcasecmp.o string/strncasecmp.o stdlib/mkstemp.o string/strtok.o unistd/execvp.o unistd/_exit.o ctype/isalnum.o time/ctime_r.o stdlib/strtold.o sys/time/gettimeofday.o stdio/fgetpos.o stdio/fsetpos.o ctype/isprint.o stdlib/system.o stdio/tmpnam.o unistd/msleep.o stdlib/atof.o stdlib/strtod.o stdio/rename.o sys/stat/mkdir.o unistd/uptime.o
+OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o libgen/basename.o string/strdup.o string/strndup.o string/strlcpy.o stdlib/atexit.o stdio/open_memstream.o libgen/dirname.o unistd/unlink.o string/strstr.o string/strcasecmp.o string/strncasecmp.o stdlib/mkstemp.o string/strtok.o unistd/execvp.o unistd/_exit.o ctype/isalnum.o time/ctime_r.o stdlib/strtold.o sys/time/gettimeofday.o stdio/fgetpos.o stdio/fsetpos.o ctype/isprint.o stdlib/system.o stdio/tmpnam.o unistd/msleep.o stdlib/atof.o stdlib/strtod.o stdio/rename.o sys/stat/mkdir.o unistd/uptime.o unistd/ftruncate.o
all: libc.a
%.o: %.c
diff --git a/userland/libc/include/unistd.h b/userland/libc/include/unistd.h
index e43dc33..7d74097 100644
--- a/userland/libc/include/unistd.h
+++ b/userland/libc/include/unistd.h
@@ -10,7 +10,7 @@ extern int opterr, optind, optopt;
extern char *optarg;
int close(int fildes);
-int ftruncate(int fildes, uint64_t length);
+int ftruncate(int fildes, size_t length);
int execv(char *path, char **argv);
int pipe(int fd[2]);
int dup2(int org_fd, int new_fd);
diff --git a/userland/libc/libc.c b/userland/libc/libc.c
index 90c0323..e2f064d 100644
--- a/userland/libc/libc.c
+++ b/userland/libc/libc.c
@@ -315,8 +315,3 @@ int shm_open(const char *name, int oflag, mode_t mode) {
};
RC_ERRNO(syscall(SYS_SHM_OPEN, &args, 0, 0, 0, 0));
}
-
-int ftruncate(int fildes, uint64_t length) {
- SYS_FTRUNCATE_PARAMS args = {.fildes = fildes, .length = length};
- RC_ERRNO(syscall(SYS_FTRUNCATE, &args, 0, 0, 0, 0));
-}
diff --git a/userland/libc/unistd/ftruncate.c b/userland/libc/unistd/ftruncate.c
new file mode 100644
index 0000000..cf35944
--- /dev/null
+++ b/userland/libc/unistd/ftruncate.c
@@ -0,0 +1,6 @@
+#include <syscall.h>
+#include <unistd.h>
+
+int ftruncate(int fildes, size_t length) {
+ RC_ERRNO(syscall(SYS_FTRUNCATE, fildes, length, 0, 0, 0));
+}