Create libioutil, implement a filewriter
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m21s

This commit is contained in:
2026-03-02 22:47:10 +01:00
parent 27afd57427
commit 58c515e90a
28 changed files with 231 additions and 29 deletions

View File

@@ -11,3 +11,4 @@ include make/libstring.mk
include make/libkb.mk include make/libkb.mk
include make/libaux.mk include make/libaux.mk
include make/libarena.mk include make/libarena.mk
include make/libioutil.mk

View File

@@ -11,3 +11,4 @@ make -B all_compiledb_libstring
make -B all_compiledb_libkb make -B all_compiledb_libkb
make -B all_compiledb_libaux make -B all_compiledb_libaux
make -B all_compiledb_libarena make -B all_compiledb_libarena
make -B all_compiledb_libioutil

View File

@@ -16,6 +16,7 @@ make -B all_libstring
make -B all_libkb make -B all_libkb
make -B all_libaux make -B all_libaux
make -B all_libarena make -B all_libarena
make -B all_libioutil
make -B all_apps make -B all_apps
make -B all_dist make -B all_dist
./aux/limine_iso_amd64.sh ./aux/limine_iso_amd64.sh

View File

@@ -12,5 +12,6 @@ make -B docs_libterminal
make -B docs_libkb make -B docs_libkb
make -B docs_libaux make -B docs_libaux
make -B docs_libarena make -B docs_libarena
make -B docs_libioutil
mkdocs build mkdocs build

View File

@@ -11,4 +11,5 @@ make -B format_libstring
make -B format_libkb make -B format_libkb
make -B format_libaux make -B format_libaux
make -B format_libarena make -B format_libarena
make -B format_libioutil
make -B format_apps make -B format_apps

View File

@@ -4,6 +4,7 @@ $(eval $(call add_lib,libstring))
$(eval $(call add_lib,libprocess)) $(eval $(call add_lib,libprocess))
$(eval $(call add_lib,libaux)) $(eval $(call add_lib,libaux))
$(eval $(call add_lib,libarena)) $(eval $(call add_lib,libarena))
$(eval $(call add_lib,libioutil))
$(eval $(call add_include,libterminal)) $(eval $(call add_include,libterminal))
cflags += -DPRINTF_INCLUDE_CONFIG_H=1 cflags += -DPRINTF_INCLUDE_CONFIG_H=1

29
ce/ce.c
View File

@@ -1,5 +1,6 @@
#include <arena.h> #include <arena.h>
#include <desc.h> #include <desc.h>
#include <filewriter.h>
#include <liballoc.h> #include <liballoc.h>
#include <list.h> #include <list.h>
#include <minmax.h> #include <minmax.h>
@@ -546,15 +547,33 @@ static void execute_redir (struct ast_redir* redir, struct context* context) {
return; return;
} }
if ((ret = volume_open (volume)) < 0) { struct filewriter fw;
cprintf (context, "ERROR could not open volume '%s': %s\n", volume, str_status[-ret]); if ((ret = filewriter_init (&fw, volume, path, FW_CREATE_FILE | FW_APPEND)) < 0) {
cprintf (context, "ERROR could not initialize filewriter for '%s:%s'\n", volume, path);
return; return;
} }
create_file (path); size_t chunk_size = 1024;
write_file (path, 0, (uint8_t*)context->strbuf.items, context->strbuf.count - 1); size_t chunks = (context->strbuf.count - 1) / chunk_size;
size_t rem = (context->strbuf.count - 1) % chunk_size;
volume_close (); for (size_t chunk = 0; chunk < chunks; chunk++) {
if ((ret = filewriter_write (&fw, (uint8_t*)&context->strbuf.items[chunk * chunk_size],
chunk_size)) < 0) {
filewriter_fini (&fw);
cprintf (context, "ERROR filewriter failed to write to '%s:%s'\n", volume, path);
return;
}
}
if ((ret = filewriter_write (&fw, (uint8_t*)&context->strbuf.items[chunks * chunk_size], rem)) <
0) {
filewriter_fini (&fw);
cprintf (context, "ERROR filewriter failed to write to '%s:%s'\n", volume, path);
return;
}
filewriter_fini (&fw);
} }
static void execute (struct ast_node* root, struct context* context) { static void execute (struct ast_node* root, struct context* context) {

9
include/map.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef _MAP_H
#define _MAP_H
#define MAP_PRESENT (1 << 0)
#define MAP_RW (1 << 1)
#define MAP_USER (1 << 2)
#define MAP_FLAGS (MAP_PRESENT | MAP_USER)
#endif // _MAP_H

8
include/page_size.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef _PAGE_SIZE_H
#define _PAGE_SIZE_H
#if defined(__x86_64__)
#define PAGE_SIZE 4096
#endif
#endif // _PAGE_SIZE_H

6
include/write_file.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef _WRITE_FILE_H
#define _WRITE_FILE_H
#define WF_APPEND (1 << 0)
#endif // _WRITE_FILE_H

View File

@@ -14,6 +14,7 @@
#include <path_defs.h> #include <path_defs.h>
#include <status.h> #include <status.h>
#include <sys/debug.h> #include <sys/debug.h>
#include <write_file.h>
static int fat1_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* buffer, static int fat1_diskio_read (struct fatfs_ctx* ctx, uint32_t sector, uint8_t* buffer,
uint32_t sector_count) { uint32_t sector_count) {
@@ -196,13 +197,18 @@ int fatfs_read_file (struct vfs_volume* volume, const char* path, uint8_t* buffe
} }
int fatfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int fatfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size) { size_t size, uint32_t flags) {
struct fatfs_ctx* fatfs_ctx = volume->udata; struct fatfs_ctx* fatfs_ctx = volume->udata;
if (fl_is_dir (fatfs_ctx, path)) if (fl_is_dir (fatfs_ctx, path))
return -ST_NOT_FOUND; return -ST_NOT_FOUND;
FL_FILE* file = fl_fopen (fatfs_ctx, path, "wb+"); FL_FILE* file;
if ((flags & WF_APPEND))
file = fl_fopen (fatfs_ctx, path, "wb+");
else
file = fl_fopen (fatfs_ctx, path, "wb");
if (file == NULL) if (file == NULL)
return -ST_NOT_FOUND; return -ST_NOT_FOUND;

View File

@@ -22,7 +22,7 @@ int fatfs_read_file (struct vfs_volume* volume, const char* path, uint8_t* buffe
size_t size); size_t size);
int fatfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int fatfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size); size_t size, uint32_t flags);
int fatfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry, int fatfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
size_t entry_num); size_t entry_num);

View File

@@ -199,8 +199,8 @@ int tarfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct di
} }
int tarfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int tarfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size) { size_t size, uint32_t flags) {
(void)volume, (void)path, (void)buffer, (void)off, (void)size; (void)volume, (void)path, (void)buffer, (void)off, (void)size, (void)flags;
return ST_OK; return ST_OK;
} }

View File

@@ -44,7 +44,7 @@ int tarfs_read_file (struct vfs_volume* volume, const char* path, uint8_t* buffe
size_t size); size_t size);
int tarfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int tarfs_write_file (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size); size_t size, uint32_t flags);
int tarfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry, int tarfs_read_dir_entry (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
size_t entry_num); size_t entry_num);

View File

@@ -206,7 +206,7 @@ int vfs_read_file (struct proc* proc, const char* volume_name, const char* path,
} }
int vfs_write_file (struct proc* proc, const char* volume_name, const char* path, uint8_t* buffer, int vfs_write_file (struct proc* proc, const char* volume_name, const char* path, uint8_t* buffer,
size_t off, size_t size) { size_t off, size_t size, uint32_t flags) {
struct vfs_volume* volume = vfs_find_volume (volume_name); struct vfs_volume* volume = vfs_find_volume (volume_name);
if (volume == NULL) if (volume == NULL)
@@ -221,7 +221,7 @@ int vfs_write_file (struct proc* proc, const char* volume_name, const char* path
spin_unlock (&volume->lock); spin_unlock (&volume->lock);
return volume->driver_ops.write_file (volume, path, buffer, off, size); return volume->driver_ops.write_file (volume, path, buffer, off, size, flags);
} }
int vfs_create_file (struct proc* proc, const char* volume_name, const char* path) { int vfs_create_file (struct proc* proc, const char* volume_name, const char* path) {

View File

@@ -42,7 +42,7 @@ struct vfs_volume {
size_t size); size_t size);
int (*write_file) (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off, int (*write_file) (struct vfs_volume* volume, const char* path, uint8_t* buffer, size_t off,
size_t size); size_t size, uint32_t flags);
int (*read_dir_entry) (struct vfs_volume* volume, const char* path, struct dir_entry* entry, int (*read_dir_entry) (struct vfs_volume* volume, const char* path, struct dir_entry* entry,
size_t entry_num); size_t entry_num);
@@ -70,7 +70,7 @@ int vfs_read_file (struct proc* proc, const char* volume, const char* path, uint
size_t off, size_t size); size_t off, size_t size);
int vfs_write_file (struct proc* proc, const char* volume, const char* path, uint8_t* buffer, int vfs_write_file (struct proc* proc, const char* volume, const char* path, uint8_t* buffer,
size_t off, size_t size); size_t off, size_t size, uint32_t flags);
int vfs_describe (struct proc* proc, const char* volume, const char* path, struct desc* desc); int vfs_describe (struct proc* proc, const char* volume, const char* path, struct desc* desc);

View File

@@ -21,6 +21,7 @@
#include <sys/proc.h> #include <sys/proc.h>
#include <syscall/syscall.h> #include <syscall/syscall.h>
#include <syscall_defs.h> #include <syscall_defs.h>
#include <write_file.h>
#define DEFINE_SYSCALL(name) \ #define DEFINE_SYSCALL(name) \
uintptr_t name (struct proc* UNUSED proc, void* UNUSED regs, struct reschedule_ctx* UNUSED rctx, \ uintptr_t name (struct proc* UNUSED proc, void* UNUSED regs, struct reschedule_ctx* UNUSED rctx, \
@@ -503,12 +504,13 @@ DEFINE_SYSCALL (sys_create_file) {
return SYSRESULT (ret); return SYSRESULT (ret);
} }
/* int write_file (char* path, size_t off, uint8_t* buffer, size_t size) */ /* int write_file (char* path, size_t off, uint8_t* buffer, size_t size, uint32_t flags) */
DEFINE_SYSCALL (sys_write_file) { DEFINE_SYSCALL (sys_write_file) {
uintptr_t uvaddr_path = a1; uintptr_t uvaddr_path = a1;
size_t off = (size_t)a2; size_t off = (size_t)a2;
uintptr_t uvaddr_buffer = a3; uintptr_t uvaddr_buffer = a3;
size_t size = (size_t)a4; size_t size = (size_t)a4;
uint32_t flags = (uint32_t)a5;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response; struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
@@ -529,7 +531,7 @@ DEFINE_SYSCALL (sys_write_file) {
return SYSRESULT (-ST_BAD_ADDRESS_SPACE); return SYSRESULT (-ST_BAD_ADDRESS_SPACE);
spin_lock (&proc->lock); spin_lock (&proc->lock);
int ret = vfs_write_file (proc, proc->cwv, path, buffer, off, size); int ret = vfs_write_file (proc, proc->cwv, path, buffer, off, size, flags);
spin_unlock (&proc->lock); spin_unlock (&proc->lock);
return SYSRESULT (ret); return SYSRESULT (ret);

View File

@@ -2,6 +2,8 @@
#pragma clang optimize off #pragma clang optimize off
#include <liballoc.h> #include <liballoc.h>
#include <map.h>
#include <page_size.h>
#include <system.h> #include <system.h>
int liballoc_mutex; int liballoc_mutex;

4
libioutil/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.o
*.json
docs/
.cache/

8
libioutil/Makefile Normal file
View File

@@ -0,0 +1,8 @@
include ../make/ufuncs.mk
$(eval $(call add_include,libsystem))
$(eval $(call add_include,libstring))
libname := libioutil
include ../make/lib.mk

83
libioutil/filewriter.c Normal file
View File

@@ -0,0 +1,83 @@
#include <desc.h>
#include <filewriter.h>
#include <path_defs.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <system.h>
#include <write_file.h>
int filewriter_init (struct filewriter* fw, const char* volume, const char* path, uint32_t flags) {
memset (fw, 0, sizeof (*fw));
strncpy (fw->volume, volume, VOLUME_MAX);
strncpy (fw->path, path, PATH_MAX);
fw->flags = flags;
int ret;
struct desc desc;
if ((ret = volume_open (fw->volume)) < 0)
return -FW_VOLUME_OPEN_ERROR;
if ((fw->flags & FW_CREATE_FILE)) {
if ((ret = create_file (fw->path)) < 0) {
volume_close ();
return -FW_CREATE_FILE_ERROR;
}
}
if ((ret = describe (fw->path, &desc)) < 0) {
volume_close ();
return -FW_DESC_ERROR;
}
if (desc.type != FS_FILE)
return -FW_NOT_FILE;
fw->file_size = desc.size;
fw->flags |= FW_OPEN;
if ((fw->flags & FW_APPEND))
fw->write_cursor = desc.size;
return FW_OK;
}
int filewriter_fini (struct filewriter* fw) {
if ((fw->flags & FW_OPEN)) {
volume_close ();
fw->flags &= ~FW_OPEN;
}
return FW_OK;
}
int filewriter_write (struct filewriter* fw, uint8_t* buffer, size_t buffer_size) {
if (!(fw->flags & FW_OPEN))
return -FW_VOLUME_NOT_OPENED;
struct desc desc;
int ret;
if ((fw->flags & FW_APPEND)) {
if ((ret = describe (fw->path, &desc)) < 0)
return -FW_DESC_ERROR;
fw->file_size = desc.size;
fw->write_cursor = fw->file_size;
}
if (buffer_size > 0) {
if (!(fw->flags & FW_APPEND) && !(fw->write_cursor + buffer_size <= fw->file_size))
return -FW_CURSOR_OOB;
uint32_t flags = (fw->flags & FW_APPEND) ? WF_APPEND : 0;
if ((ret = write_file (fw->path, fw->write_cursor, buffer, buffer_size, flags)) < 0)
return -FW_WRITE_ERROR;
fw->write_cursor += buffer_size;
}
return FW_OK;
}

36
libioutil/filewriter.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef _LIBIOUTIL_FILEWRITER_H
#define _LIBIOUTIL_FILEWRITER_H
#include <path_defs.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define FW_OK 0
#define FW_VOLUME_OPEN_ERROR 1
#define FW_DESC_ERROR 2
#define FW_NOT_FILE 3
#define FW_VOLUME_NOT_OPENED 4
#define FW_WRITE_ERROR 5
#define FW_CURSOR_OOB 6
#define FW_CREATE_FILE_ERROR 7
#define FW_CREATE_FILE (1 << 0)
#define FW_APPEND (1 << 1)
#define FW_OPEN (1 << 31)
struct filewriter {
char volume[VOLUME_MAX];
char path[PATH_MAX];
size_t write_cursor;
size_t file_size;
uint32_t flags;
};
int filewriter_init (struct filewriter* fw, const char* volume, const char* path, uint32_t flags);
int filewriter_fini (struct filewriter* fw);
int filewriter_write (struct filewriter* fw, uint8_t* buffer, size_t buffer_size);
#endif // _LIBIOUTIL_FILEWRITER_H

3
libioutil/src.mk Normal file
View File

@@ -0,0 +1,3 @@
c += filewriter.c
o += filewriter.o

View File

@@ -1,4 +1,6 @@
#include <liballoc.h> #include <liballoc.h>
#include <map.h>
#include <page_size.h>
#include <process.h> #include <process.h>
#include <status.h> #include <status.h>
#include <stddef.h> #include <stddef.h>

View File

@@ -1,6 +1,7 @@
#ifndef _LIBPROCESS_PROCESS_PROCESS_H #ifndef _LIBPROCESS_PROCESS_PROCESS_H
#define _LIBPROCESS_PROCESS_PROCESS_H #define _LIBPROCESS_PROCESS_PROCESS_H
#include <page_size.h>
#include <system.h> #include <system.h>
/* Size of process' stack */ /* Size of process' stack */

View File

@@ -71,8 +71,8 @@ int read_dir_entry (const char* path, struct dir_entry* entry, size_t entry_num)
int create_file (const char* path) { return (int)do_syscall (SYS_CREATE_FILE, path); } int create_file (const char* path) { return (int)do_syscall (SYS_CREATE_FILE, path); }
int write_file (const char* path, size_t off, uint8_t* buffer, size_t size) { int write_file (const char* path, size_t off, uint8_t* buffer, size_t size, uint32_t flags) {
return (int)do_syscall (SYS_WRITE_FILE, path, off, buffer, size); return (int)do_syscall (SYS_WRITE_FILE, path, off, buffer, size, flags);
} }
int wait_for_pid (int pid) { return (int)do_syscall (SYS_WAIT_FOR_PID, pid); } int wait_for_pid (int pid) { return (int)do_syscall (SYS_WAIT_FOR_PID, pid); }

View File

@@ -6,15 +6,6 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#if defined(__x86_64__)
#define PAGE_SIZE 4096
#endif
#define MAP_PRESENT (1 << 0)
#define MAP_RW (1 << 1)
#define MAP_USER (1 << 2)
#define MAP_FLAGS (MAP_PRESENT | MAP_USER)
/* Quit the current running process */ /* Quit the current running process */
int quit (void); int quit (void);
@@ -85,7 +76,7 @@ int read_dir_entry (const char* path, struct dir_entry* entry, size_t entry_num)
int create_file (const char* path); int create_file (const char* path);
/* write to a file */ /* write to a file */
int write_file (const char* path, size_t off, uint8_t* buffer, size_t size); int write_file (const char* path, size_t off, uint8_t* buffer, size_t size, uint32_t flags);
/* wait for process */ /* wait for process */
int wait_for_pid (int pid); int wait_for_pid (int pid);

16
make/libioutil.mk Normal file
View File

@@ -0,0 +1,16 @@
all_libioutil:
make -C libioutil platform=$(platform) all
all_compiledb_libioutil:
bear --output libioutil/compile_commands.json -- make -C libioutil platform=$(platform) all
clean_libioutil:
make -C libioutil platform=$(platform) clean
format_libioutil:
make -C libioutil platform=$(platform) format
docs_libioutil:
make -C libioutil platform=$(platform) docs
.PHONY: all_libioutil clean_libioutil format_libioutil docs_libioutil all_compiledb_libioutil