From: kosmirror <kos...@us...> - 2025-09-25 15:39:47
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via d8f7df2599dc3e147ae585855f396d74e8a28ef4 (commit) via 183f3caa980500ee5ef4386920befd0ba2077fb9 (commit) via 57eac6bf98c1b549df19e81efd433161f846f24c (commit) via b8ca37df81ce110ef6156c118fc04d9a0b236b6e (commit) via be56dc0eef09b433f6bb50f260c482c865b6c382 (commit) via dc2f7b2e5524557dbb03f676d296c680edc31bb1 (commit) via 8a0b8d10df3819988dfb1495a2cb1ea3af7e6bc3 (commit) via 43b0ab08ef9cd8b51a060d2cec0c5598394d05c6 (commit) via 5eaa446f8e63def5a245b011d2418e306f1e36af (commit) via 4d71ba186d4a9ca2a7fa5f375841dcdb6578ccc9 (commit) via 583490490f4c194821c95aec365d1a65635be9ac (commit) via 1cf3ca4c592700e1799a057a1d9076caa646e3fd (commit) via 946586d1ad3349e1381dde236990d1bae986cb3e (commit) via 530af522581825b4ae9152e68357bb5a168079eb (commit) via ab38ca87b30f641d50fdf5b35ad357b370b1c469 (commit) via 4837c4b9b8a3481ba5f02c6f66b904e629007fa2 (commit) via b62400ea86be0266c095fa80a72aefe1caa06f2d (commit) via 4daa9835b384abe87fbeef274a5e434e43d5207a (commit) via 826789b2574552848bdd0b1b4160f96da2947805 (commit) from 2babea38ec32a10203c373a9d77b53cf3d1a8d53 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d8f7df2599dc3e147ae585855f396d74e8a28ef4 Author: QuzarDC <qu...@co...> Date: Sun Sep 21 19:50:18 2025 -0400 fs_dcload: Drop dir list. The dir list was a means to track which handles were dirs or not. Instead use the `path` member of the object to do the same and return an opaque token to that object rather than the `hnd` used by the host-side. commit 183f3caa980500ee5ef4386920befd0ba2077fb9 Author: QuzarDC <qu...@co...> Date: Sun Sep 21 18:41:10 2025 -0400 fs_dcload: Set errno on not finding a file. `ENOENT` to match the `ENOTDIR` set by the dir path. commit 57eac6bf98c1b549df19e81efd433161f846f24c Author: QuzarDC <qu...@co...> Date: Wed Jun 25 04:11:50 2025 -0400 Update filebrowser example to show file stats. Simple addition to draw the Filesize and modification time as provided by stat. Was updated in order to help validate functionality of stat over `/pc/` after updating to use a standardized stat rather than custom dcload one. commit b8ca37df81ce110ef6156c118fc04d9a0b236b6e Author: QuzarDC <qu...@co...> Date: Tue Jun 24 20:18:55 2025 -0400 fs_dcload: Protect against possible buffer overflow in readdir. commit be56dc0eef09b433f6bb50f260c482c865b6c382 Author: QuzarDC <qu...@co...> Date: Tue Jun 24 17:17:12 2025 -0400 dcload: Replace dcload_dirent with our standard one. The sizes and defined types match. The risk in doing this is only in if the host side needs to change its data types. In that case though, there would have to be changes on the KOS side as well. commit dc2f7b2e5524557dbb03f676d296c680edc31bb1 Author: QuzarDC <qu...@co...> Date: Tue Jun 24 15:52:46 2025 -0400 dcload: Implement each unimplemented dcload command. chdir, chmod, fstat, time, utime, and exit had never been implemented in KOS. utime has been left as a commented out stub to note how there would likely need to be updates to the tool in order for it to work. commit 8a0b8d10df3819988dfb1495a2cb1ea3af7e6bc3 Author: QuzarDC <qu...@co...> Date: Tue Jun 24 03:58:05 2025 -0400 dcload: Whitespace and junk cleanup. Mostly moving stars, but also some lining up of comments and removal of a prototype that had no function. commit 43b0ab08ef9cd8b51a060d2cec0c5598394d05c6 Author: QuzarDC <qu...@co...> Date: Tue Jun 24 02:11:44 2025 -0400 dcload: Add assignwrkmem function. commit 5eaa446f8e63def5a245b011d2418e306f1e36af Author: QuzarDC <qu...@co...> Date: Tue Jun 24 03:50:02 2025 -0400 dcload: Add dir related functions. Open, close, read, and rewind. Additionally move the dirent type over. commit 4d71ba186d4a9ca2a7fa5f375841dcdb6578ccc9 Author: QuzarDC <qu...@co...> Date: Tue Jun 24 03:28:47 2025 -0400 dcload: Create function for stat. Bigger than others as the bespoke stat type was moved. commit 583490490f4c194821c95aec365d1a65635be9ac Author: QuzarDC <qu...@co...> Date: Tue Jun 24 03:19:16 2025 -0400 dcload: Create functions for link, unlink, and lseek. commit 1cf3ca4c592700e1799a057a1d9076caa646e3fd Author: QuzarDC <qu...@co...> Date: Tue Jun 24 03:04:36 2025 -0400 dcload: Create functions for read, write, open, and close commands. commit 946586d1ad3349e1381dde236990d1bae986cb3e Author: QuzarDC <qu...@co...> Date: Tue Jun 24 02:53:30 2025 -0400 dcload: Create function for `gethostinfo` command. commit 530af522581825b4ae9152e68357bb5a168079eb Author: QuzarDC <qu...@co...> Date: Tue Jun 24 02:43:34 2025 -0400 dcload: Move gdb packet function to new file. commit ab38ca87b30f641d50fdf5b35ad357b370b1c469 Author: QuzarDC <qu...@co...> Date: Tue Jun 24 02:04:31 2025 -0400 dcload: Rename internal vfs functions. To follow our standard naming convention as well as `dcloadgetgdbpacket` a lot of the syscall functions for the file ops would overlap with these names. So renaming in order to get the conflict out of the way. commit 4837c4b9b8a3481ba5f02c6f66b904e629007fa2 Author: QuzarDC <qu...@co...> Date: Mon Jun 23 20:33:07 2025 -0400 fs_dcload: Reduce scope and severity of locking. Currently `fs_dcload` uses fairly broad spinlocks over most of each function. From the history it looks as though these are spinlocks simply because we didn't have other sorts of locks when this was originally written. It can't have to do with the actual operations as the syscall has always been called with irqs disabled. So here I make three changes: First: Implement a rwsem to protect the shared dir list. This is specifically for protecting access to that data structure. Second: Reduce the scope of the 'mutex' locks. Leave them only in cases where multiple dcload commands must be issued and we should expect that others wouldn't be issued between them. It may be that these can be shrunken down slightly more. Third: Change the spinlocks to mutexes. commit b62400ea86be0266c095fa80a72aefe1caa06f2d Author: QuzarDC <qu...@co...> Date: Mon Jun 23 15:06:27 2025 -0400 dcload: Change last remaining arch/types to stdint commit 4daa9835b384abe87fbeef274a5e434e43d5207a Author: QuzarDC <qu...@co...> Date: Sun Jun 22 23:36:56 2025 -0400 dcload: Migrate syscall into our BIOS syscalls file. Create a proper C function for dcload's syscall to match the way we do for other syscalls rather than as a macro wrapper around an asm file. Additionally move the definitions of the commands for the syscall to accompany it. I had considered whether this might be better as its own `syscalls-custom` since it does operate differently, including having a function to detect whether it's present or not. It may be that this could represent a defining pattern for the use of other custom syscalls from modded BIOS or alternative loaders (dcload NG/3). commit 826789b2574552848bdd0b1b4160f96da2947805 Author: QuzarDC <qu...@co...> Date: Sun May 11 01:50:52 2025 -0400 Rename and expose if the dcload syscall is installed. Removed two usages that were redundant. There is no condition where `dcload_type` could be set to `TYPE_SER` while dcload is not detected. Renamed to indicate that it's not a part of the dcload vfs. ----------------------------------------------------------------------- Summary of changes: addons/libppp/ppp_scif.c | 2 +- examples/dreamcast/filesystem/browse/browse.c | 44 +++- examples/dreamcast/filesystem/browse/browse.h | 2 + kernel/arch/dreamcast/fs/Makefile | 3 +- kernel/arch/dreamcast/fs/dcload-syscall.s | 19 -- kernel/arch/dreamcast/fs/fs_dcload.c | 296 +++++++++++--------------- kernel/arch/dreamcast/fs/fs_dclsocket.c | 15 +- kernel/arch/dreamcast/hardware/Makefile | 2 +- kernel/arch/dreamcast/hardware/dcload.c | 134 ++++++++++++ kernel/arch/dreamcast/hardware/scif-spi.c | 2 +- kernel/arch/dreamcast/include/dc/dcload.h | 114 ++++++++++ kernel/arch/dreamcast/include/dc/fs_dcload.h | 74 +------ kernel/arch/dreamcast/kernel/gdb_stub.c | 2 +- kernel/arch/dreamcast/kernel/init.c | 3 +- 14 files changed, 427 insertions(+), 285 deletions(-) delete mode 100644 kernel/arch/dreamcast/fs/dcload-syscall.s create mode 100644 kernel/arch/dreamcast/hardware/dcload.c create mode 100644 kernel/arch/dreamcast/include/dc/dcload.h diff --git a/addons/libppp/ppp_scif.c b/addons/libppp/ppp_scif.c index c22aacca..ed57902d 100644 --- a/addons/libppp/ppp_scif.c +++ b/addons/libppp/ppp_scif.c @@ -80,7 +80,7 @@ static ppp_device_t scif_dev = { int ppp_scif_init(int bps) { /* Make sure we're not using dcload-serial. If we are, we really shouldn't take over the serial port from it. */ - if(*DCLOADMAGICADDR == DCLOADMAGICVALUE && dcload_type == DCLOAD_TYPE_SER) { + if(dcload_type == DCLOAD_TYPE_SER) { dbglog(DBG_KDEBUG, "ppp_scif_init: aborting -- using dcload-serial.\n"); return -1; } diff --git a/examples/dreamcast/filesystem/browse/browse.c b/examples/dreamcast/filesystem/browse/browse.c index ccd3bf29..35552ffc 100644 --- a/examples/dreamcast/filesystem/browse/browse.c +++ b/examples/dreamcast/filesystem/browse/browse.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) { directory_file_t directory_contents[100]; bool prompting = false; + bool statting = false; bool highlight_yes = true; bool mounted_sd = false; bool changed_directory = true; @@ -74,8 +75,14 @@ int main(int argc, char **argv) { changed_buttons = current_buttons ^ previous_buttons; previous_buttons = current_buttons; + /* Clear the stat if any button is pressed */ + if(statting && button_pressed(current_buttons, changed_buttons, 0)) { + statting = false; /* Get us out of captivity */ + changed_directory = true; /* Force redraw of the screen to clear stat */ + } + /* Enter a directory */ - if(button_pressed(current_buttons, changed_buttons, CONT_A)) { + else if(button_pressed(current_buttons, changed_buttons, CONT_A)) { if(prompting) { prompting = false; changed_directory = true; @@ -134,7 +141,7 @@ int main(int argc, char **argv) { } /* Exit a directory */ - if(button_pressed(current_buttons, changed_buttons, CONT_B)) { + else if(button_pressed(current_buttons, changed_buttons, CONT_B)) { if(prompting) { prompting = false; changed_directory = true; @@ -156,9 +163,19 @@ int main(int argc, char **argv) { } } } + + /* Stat an entry */ + else if(button_pressed(current_buttons, changed_buttons, CONT_Y)) { + if(!prompting) { + memset(directory_temp, 0, BUFFER_LENGTH); + fs_path_append(directory_temp, current_directory, BUFFER_LENGTH); + fs_path_append(directory_temp, directory_contents[selector_index].filename, BUFFER_LENGTH); + statting = draw_stat(directory_temp); + } + } /* Navigate the directory */ - if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { + else if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_DOWN)) { if(prompting) { highlight_yes = !highlight_yes; show_prompt(current_directory, mounted_sd, highlight_yes); @@ -170,7 +187,7 @@ int main(int argc, char **argv) { } } } - if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { + else if(button_pressed(current_buttons, changed_buttons, CONT_DPAD_UP)) { if(prompting) { highlight_yes = !highlight_yes; show_prompt(current_directory, mounted_sd, highlight_yes); @@ -184,7 +201,7 @@ int main(int argc, char **argv) { } /* Exit Program */ - if(button_pressed(current_buttons, changed_buttons, CONT_START)) + else if(button_pressed(current_buttons, changed_buttons, CONT_START)) break; /* Update the screen if we navigate a directory */ @@ -353,6 +370,23 @@ static void draw_directory_contents(directory_file_t *directory_contents, int nu } } +static bool draw_stat(const char *path) { + int x = 20 + BFONT_HEIGHT, y = 350; + struct stat path_stat; + + /* If stat fails */ + if(stat(path, &path_stat) < 0) + return false; + + /* We got a stat, so lets draw it */ + bfont_draw_str_fmt(vram_s + y*SCREEN_WIDTH+x, SCREEN_WIDTH, true, + "Stat succeeded:\n\tFile size: %lu\n\tLast Modified: %s\n", + S_ISDIR(path_stat.st_mode) ? 0 : path_stat.st_size, + asctime(gmtime(&path_stat.st_mtime))); + + return true; +} + static cont_state_t *get_cont_state() { maple_device_t *cont; cont_state_t *state; diff --git a/examples/dreamcast/filesystem/browse/browse.h b/examples/dreamcast/filesystem/browse/browse.h index 2aa62012..506c39db 100644 --- a/examples/dreamcast/filesystem/browse/browse.h +++ b/examples/dreamcast/filesystem/browse/browse.h @@ -17,6 +17,8 @@ static void delete_file(char *filename, bool mounted_sd); static void prompt_message(char *message, bool highlight_yes); +static bool draw_stat(const char *path); + static void draw_directory_selector(int index); static void draw_directory_contents(directory_file_t *directory_contents, int num); diff --git a/kernel/arch/dreamcast/fs/Makefile b/kernel/arch/dreamcast/fs/Makefile index 2fbcde5c..0e080ec3 100644 --- a/kernel/arch/dreamcast/fs/Makefile +++ b/kernel/arch/dreamcast/fs/Makefile @@ -6,8 +6,7 @@ # Dreamcast-specific file systems -OBJS = fs_iso9660.o fs_vmu.o fs_dcload.o dcload-syscall.o vmufs.o \ - fs_dclsocket.o +OBJS = fs_iso9660.o fs_vmu.o fs_dcload.o vmufs.o fs_dclsocket.o SUBDIRS = include $(KOS_BASE)/Makefile.prefab diff --git a/kernel/arch/dreamcast/fs/dcload-syscall.s b/kernel/arch/dreamcast/fs/dcload-syscall.s deleted file mode 100644 index 80976acb..00000000 --- a/kernel/arch/dreamcast/fs/dcload-syscall.s +++ /dev/null @@ -1,19 +0,0 @@ -! KallistiOS ##version## -! -! dcload-syscall.s -! (c)2000-2001 Andrew Kieschnick -! - - .section .text - .global _dcloadsyscall - -_dcloadsyscall: - mov.l dcloadsyscall_k,r0 - mov.l @r0,r0 - jmp @r0 - nop - -.align 4 -dcloadsyscall_k: - .long 0x8c004008 - diff --git a/kernel/arch/dreamcast/fs/fs_dcload.c b/kernel/arch/dreamcast/fs/fs_dcload.c index 93e7ca5e..fb17f46c 100644 --- a/kernel/arch/dreamcast/fs/fs_dcload.c +++ b/kernel/arch/dreamcast/fs/fs_dcload.c @@ -18,62 +18,35 @@ printf goes to the dc-tool console */ -#include <dc/fifo.h> +#include <dc/dcload.h> #include <dc/fs_dcload.h> -#include <arch/spinlock.h> #include <kos/dbgio.h> #include <kos/dbglog.h> #include <kos/fs.h> #include <kos/init.h> +#include <kos/mutex.h> +#include <kos/rwsem.h> #include <errno.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/dirent.h> #include <sys/queue.h> -/* A linked list of dir entries. */ -typedef struct dcl_dir { - LIST_ENTRY(dcl_dir) fhlist; +typedef struct dcl_obj { int hnd; char *path; dirent_t dirent; -} dcl_dir_t; +} dcl_obj_t; -LIST_HEAD(dcl_de, dcl_dir); +static mutex_t mutex = MUTEX_INITIALIZER; -static struct dcl_de dir_head = LIST_HEAD_INITIALIZER(0); - -static dcl_dir_t *hnd_is_dir(int hnd) { - dcl_dir_t *i; - - if(!hnd) return NULL; - - LIST_FOREACH(i, &dir_head, fhlist) { - if(i->hnd == (int)hnd) - break; - } - - return i; -} - -static spinlock_t mutex = SPINLOCK_INITIALIZER; - -#define dclsc(...) ({ \ - irq_disable_scoped(); \ - while(FIFO_STATUS & FIFO_SH4) \ - ; \ - dcloadsyscall(__VA_ARGS__); \ - }) - -/* Printk replacement */ - -int dcload_write_buffer(const uint8 *data, int len, int xlat) { +int dcload_write_buffer(const uint8_t *data, int len, int xlat) { (void)xlat; - spinlock_lock_scoped(&mutex); - dclsc(DCLOAD_WRITE, 1, data, len); + dcload_write(STDOUT_FILENO, data, len); return len; } @@ -82,18 +55,8 @@ int dcload_read_cons(void) { return -1; } -size_t dcload_gdbpacket(const char* in_buf, size_t in_size, char* out_buf, size_t out_size) { - - spinlock_lock_scoped(&mutex); - - /* we have to pack the sizes together because the dcloadsyscall handler - can only take 4 parameters */ - return dclsc(DCLOAD_GDBPACKET, in_buf, (in_size << 16) | (out_size & 0xffff), out_buf); -} - -static void *dcload_open(vfs_handler_t * vfs, const char *fn, int mode) { - char *dcload_path = NULL; - dcl_dir_t *entry; +static void *fs_dcload_open(vfs_handler_t *vfs, const char *fn, int mode) { + dcl_obj_t *entry; int hnd = 0; int dcload_mode = 0; int mm = (mode & O_MODE_MASK); @@ -101,14 +64,18 @@ static void *dcload_open(vfs_handler_t * vfs, const char *fn, int mode) { (void)vfs; - spinlock_lock_scoped(&mutex); + entry = calloc(1, sizeof(dcl_obj_t)); + if(!entry) { + errno = ENOMEM; + return (void *)NULL; + } if(mode & O_DIR) { if(fn[0] == '\0') { fn = "/"; } - hnd = dclsc(DCLOAD_OPENDIR, fn); + hnd = dcload_opendir(fn); if(!hnd) { /* It could be caused by other issues, such as @@ -116,34 +83,23 @@ static void *dcload_open(vfs_handler_t * vfs, const char *fn, int mode) { ENOTDIR seems to be the best generic and we should set something */ errno = ENOTDIR; - return (void *)NULL; - } - - /* We got something back so create an dir list entry for it */ - entry = malloc(sizeof(dcl_dir_t)); - if(!entry) { - errno = ENOMEM; + free(entry); return (void *)NULL; } fn_len = strlen(fn); if(fn[fn_len - 1] == '/') fn_len--; - dcload_path = malloc(fn_len + 2); - if(!dcload_path) { + entry->path = malloc(fn_len + 2); + if(!entry->path) { errno = ENOMEM; free(entry); return (void *)NULL; } - memcpy(dcload_path, fn, fn_len); - dcload_path[fn_len] = '/'; - dcload_path[fn_len+1] = '\0'; - - /* Now that everything is ready, add to list */ - entry->hnd = hnd; - entry->path = dcload_path; - LIST_INSERT_HEAD(&dir_head, entry, fhlist); + memcpy(entry->path, fn, fn_len); + entry->path[fn_len] = '/'; + entry->path[fn_len+1] = '\0'; } else { if(mm == O_RDONLY) @@ -159,131 +115,121 @@ static void *dcload_open(vfs_handler_t * vfs, const char *fn, int mode) { if(mode & O_TRUNC) dcload_mode |= 0x0400; - hnd = dclsc(DCLOAD_OPEN, fn, dcload_mode, 0644); - hnd++; /* KOS uses 0 for error, not -1 */ + hnd = dcload_open(fn, dcload_mode, 0644); + + if(hnd == -1) { + errno = ENOENT; + free(entry); + return (void *)NULL; + } } - return (void *)hnd; + entry->hnd = hnd; + return (void *)entry; } -static int dcload_close(void * h) { - uint32 hnd = (uint32)h; - dcl_dir_t *i; +static int fs_dcload_close(void *h) { + dcl_obj_t *obj = h; - spinlock_lock_scoped(&mutex); + if(!obj) return 0; - if(hnd) { - /* Check if it's a dir */ - i = hnd_is_dir(hnd); + /* It has a path so it's a dir */ + if(obj->path) { + dcload_closedir(obj->hnd); - /* We found it in the list, so it's a dir */ - if(i) { - dclsc(DCLOAD_CLOSEDIR, hnd); - LIST_REMOVE(i, fhlist); - free(i->path); - free(i); - } - else { - hnd--; /* KOS uses 0 for error, not -1 */ - dclsc(DCLOAD_CLOSE, hnd); - } + free(obj->path); } + else + dcload_close(obj->hnd); + free(obj); return 0; } -static ssize_t dcload_read(void * h, void *buf, size_t cnt) { +static ssize_t fs_dcload_read(void *h, void *buf, size_t cnt) { ssize_t ret = -1; - uint32 hnd = (uint32)h; - - spinlock_lock_scoped(&mutex); + dcl_obj_t *obj = h; - if(hnd) { - hnd--; /* KOS uses 0 for error, not -1 */ - ret = dclsc(DCLOAD_READ, hnd, buf, cnt); - } + if(obj) + ret = dcload_read(obj->hnd, buf, cnt); return ret; } -static ssize_t dcload_write(void * h, const void *buf, size_t cnt) { +static ssize_t fs_dcload_write(void *h, const void *buf, size_t cnt) { ssize_t ret = -1; - uint32 hnd = (uint32)h; + dcl_obj_t *obj = h; - spinlock_lock_scoped(&mutex); - - if(hnd) { - hnd--; /* KOS uses 0 for error, not -1 */ - ret = dclsc(DCLOAD_WRITE, hnd, buf, cnt); - } + if(obj) + ret = dcload_write(obj->hnd, buf, cnt); return ret; } -static off_t dcload_seek(void * h, off_t offset, int whence) { +static off_t fs_dcload_seek(void *h, off_t offset, int whence) { off_t ret = -1; - uint32 hnd = (uint32)h; + dcl_obj_t *obj = h; - spinlock_lock_scoped(&mutex); - - if(hnd) { - hnd--; /* KOS uses 0 for error, not -1 */ - ret = dclsc(DCLOAD_LSEEK, hnd, offset, whence); - } + if(obj) + ret = dcload_lseek(obj->hnd, offset, whence); return ret; } -static off_t dcload_tell(void * h) { +static off_t fs_dcload_tell(void *h) { off_t ret = -1; - uint32 hnd = (uint32)h; + dcl_obj_t *obj = h; - spinlock_lock_scoped(&mutex); - - if(hnd) { - hnd--; /* KOS uses 0 for error, not -1 */ - ret = dclsc(DCLOAD_LSEEK, hnd, 0, SEEK_CUR); - } + if(obj) + ret = dcload_lseek(obj->hnd, 0, SEEK_CUR); return ret; } -static size_t dcload_total(void * h) { +static size_t fs_dcload_total(void *h) { size_t ret = -1; - size_t cur; - uint32 hnd = (uint32)h; + off_t cur; + dcl_obj_t *obj = h; - spinlock_lock_scoped(&mutex); + if(obj) { + /* Lock to ensure commands are sent sequentially. */ + mutex_lock_scoped(&mutex); - if(hnd) { - hnd--; /* KOS uses 0 for error, not -1 */ - cur = dclsc(DCLOAD_LSEEK, hnd, 0, SEEK_CUR); - ret = dclsc(DCLOAD_LSEEK, hnd, 0, SEEK_END); - dclsc(DCLOAD_LSEEK, hnd, cur, SEEK_SET); + cur = dcload_lseek(obj->hnd, 0, SEEK_CUR); + ret = dcload_lseek(obj->hnd, 0, SEEK_END); + dcload_lseek(obj->hnd, cur, SEEK_SET); } return ret; } -static dirent_t *dcload_readdir(void * h) { +static dirent_t *fs_dcload_readdir(void *h) { dirent_t *rv = NULL; - dcload_dirent_t *dcld; + struct dirent *dcld; dcload_stat_t filestat; char *fn; - uint32 hnd = (uint32)h; - dcl_dir_t *entry; + dcl_obj_t *entry = h; - spinlock_lock_scoped(&mutex); + /* Lock to ensure commands are sent sequentially. */ + mutex_lock_scoped(&mutex); ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |