From: quzar <qu...@us...> - 2024-10-08 03:33:36
|
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 feec65c7081b946d143399aa71d4f1ce61a3fd94 (commit) via fcd8e05b461efe6e5ecf742256a3becb4ac1541b (commit) via 0d1ac90ce1699d0c803d15df72174aa4098044e5 (commit) via 377a013ed3c9041af472a3bd669dd93a2255145b (commit) via 20c1927e9b862bdf9e8a661f5a71b61dd44a4c05 (commit) via 0025b088d3298c72aa40906cea7682463ab2db1f (commit) via 66b8e9066e1725be97bb537e4e67e74b0cd84941 (commit) via 96571d557ad3b7fa20222718574cbbe57db9ae4e (commit) via a3287d7b0501c30c7e91f2b5da265f4b28bc8f97 (commit) via 0e35b995bafb921af3b1f85240533fe9c95c52e3 (commit) from 33b84c21775d2fc1431558fbc9bc6c0294d93d72 (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 feec65c7081b946d143399aa71d4f1ce61a3fd94 Author: Andy Barajas <and...@gm...> Date: Mon Oct 7 20:22:24 2024 -0700 Filesystem Stat fixes (#775) * Fixed fs_vmu stat(). Added stat() to fs_romdisk. Code style changes. Fixed browser example to use fs_normalize_path instead of realpath because lstat opens and closes if a fs does not provide lstat(). * Implement/fix _stat() for used filesystems. Code cleaning/matching. commit fcd8e05b461efe6e5ecf742256a3becb4ac1541b Merge: a3287d7b 0d1ac90c Author: Donald Haase <qu...@ya...> Date: Mon Oct 7 23:19:10 2024 -0400 Merge pull request #552 from pcercuei/maple-nomem * maple: Allocate smaller status buffers Instead of unconditionally allocating one kilobyte for each possible device located in one of the 6 units of the 4 ports, for a total of 24 KiB, only allocate the status buffer to a proper size when the devices are attached to their corresponding driver. Signed-off-by: Paul Cercueil <pa...@cr...> * maple: Rework device detection mechanism Instead of having 6x4 different frames (one for each unit of each port) that are used for device detection, modify the code so that it will use one single frame for the unit 0 detection, and use unit 0's frame for sub-device detection. This will later allow to allocate devices on-demand instead of having a static array of devices. Signed-off-by: Paul Cercueil <pa...@cr...> * maple: Detach devices on shutdown Attaching the devices may have allocated memory, which we want to be reclaimed on shutdown. Signed-off-by: Paul Cercueil <pa...@cr...> * maple: Protect against allocation in IRQ context It is not always safe to call malloc() or free() in an IRQ context. Before creating a new device, make sure that memory allocation is possible. If it is not, then simply fail silently; the device will be discovered again the next time the periodic IRQ runs. * maple: Dynamically allocate devices Instead of having a huge array of 24 devices, each one with a huge DMA buffer, allocate devices dynamically when they are detected as plugged, and free them when they are detected as unplugged. * maple: driver: Alloc devices and status buffer in one allocation Instead of doing two separate allocations for one maple device and its status buffer, allocate them at once. Signed-off-by: Paul Cercueil <pa...@cr...> commit 0d1ac90ce1699d0c803d15df72174aa4098044e5 Author: Paul Cercueil <pa...@cr...> Date: Thu May 9 16:42:05 2024 +0200 maple: driver: Alloc devices and status buffer in one allocation Instead of doing two separate allocations for one maple device and its status buffer, allocate them at once. Signed-off-by: Paul Cercueil <pa...@cr...> commit 377a013ed3c9041af472a3bd669dd93a2255145b Author: Paul Cercueil <pa...@cr...> Date: Wed May 8 14:11:21 2024 +0200 maple: Dynamically allocate devices Instead of having a huge array of 24 devices, each one with a huge DMA buffer, allocate devices dynamically when they are detected as plugged, and free them when they are detected as unplugged. Signed-off-by: Paul Cercueil <pa...@cr...> commit 20c1927e9b862bdf9e8a661f5a71b61dd44a4c05 Author: Paul Cercueil <pa...@cr...> Date: Thu May 9 11:01:08 2024 +0200 maple: Protect against allocation in IRQ context It is not always safe to call malloc() or free() in an IRQ context. Before creating a new device, make sure that memory allocation is possible. If it is not, then simply fail silently; the device will be discovered again the next time the periodic IRQ runs. Signed-off-by: Paul Cercueil <pa...@cr...> commit 0025b088d3298c72aa40906cea7682463ab2db1f Author: Paul Cercueil <pa...@cr...> Date: Wed May 8 14:03:33 2024 +0200 maple: Detach devices on shutdown Attaching the devices may have allocated memory, which we want to be reclaimed on shutdown. Signed-off-by: Paul Cercueil <pa...@cr...> commit 66b8e9066e1725be97bb537e4e67e74b0cd84941 Author: Paul Cercueil <pa...@cr...> Date: Wed May 8 13:57:31 2024 +0200 maple: Rework device detection mechanism Instead of having 6x4 different frames (one for each unit of each port) that are used for device detection, modify the code so that it will use one single frame for the unit 0 detection, and use unit 0's frame for sub-device detection. This will later allow to allocate devices on-demand instead of having a static array of devices. Signed-off-by: Paul Cercueil <pa...@cr...> commit 96571d557ad3b7fa20222718574cbbe57db9ae4e Author: Paul Cercueil <pa...@cr...> Date: Wed May 1 16:46:14 2024 +0200 maple: Allocate smaller status buffers Instead of unconditionally allocating one kilobyte for each possible device located in one of the 6 units of the 4 ports, for a total of 24 KiB, only allocate the status buffer to a proper size when the devices are attached to their corresponding driver. Signed-off-by: Paul Cercueil <pa...@cr...> commit a3287d7b0501c30c7e91f2b5da265f4b28bc8f97 Author: Falco Girgis <gyr...@gm...> Date: Sat Oct 5 16:51:25 2024 -0500 Made macros for HZ and THD stack sizes overridable (#790) * Made macros for HZ and THD stack sizes overridable - Many people are starting to overrun the main kernel thread stack - We may want to eventually arrive at a better solution for providing a thread size for the kernel stack eventually, but until we get there, I think this will suffice, as it's in-line with our other overridable macros. - Added #ifdefs around HZ, THD_STACK_SIZE, and THD_KERNEL_STACK_SIZE in arch.h to only define them if they weren't already provided by the build system or externally. - Deprecated HZ, renamed to THD_SCHED_HZ. commit 0e35b995bafb921af3b1f85240533fe9c95c52e3 Author: Donald Haase <qu...@ya...> Date: Sat Oct 5 14:50:46 2024 -0400 Make the Store Queue mutex recursive (#784) * Make the Store Queue (SQ) mutex recursive. This allows for disjointed SQ locks within a single thread, which helps reduce the requirement of repeated locks/unlocks in certain paths and simplify managing the use of SQs. A static cache is used to track the data that allows a recursion depth of SQ_STATE_CACHE_SIZE which defaults to 8 and may be adjusted if needed. * It would help if I knew how asserts worked * Add name to copyright, and remove unused includes. --------- Co-authored-by: QuzarDC <qu...@co...> ----------------------------------------------------------------------- Summary of changes: addons/libkosext2fs/fs_ext2.c | 110 ++++++++------- addons/libkosfat/fs_fat.c | 49 ++++--- examples/dreamcast/filesystem/browse/browse.c | 2 +- kernel/arch/dreamcast/fs/fs_dcload.c | 44 +++--- kernel/arch/dreamcast/fs/fs_iso9660.c | 72 +++++++--- kernel/arch/dreamcast/fs/fs_vmu.c | 63 ++++----- kernel/arch/dreamcast/hardware/maple/controller.c | 1 + kernel/arch/dreamcast/hardware/maple/dreameye.c | 1 + kernel/arch/dreamcast/hardware/maple/keyboard.c | 1 + .../arch/dreamcast/hardware/maple/maple_driver.c | 64 +++++---- kernel/arch/dreamcast/hardware/maple/maple_enum.c | 9 +- .../dreamcast/hardware/maple/maple_init_shutdown.c | 29 +--- kernel/arch/dreamcast/hardware/maple/maple_irq.c | 149 ++++++++++++--------- kernel/arch/dreamcast/hardware/maple/maple_queue.c | 2 +- kernel/arch/dreamcast/hardware/maple/maple_utils.c | 2 +- kernel/arch/dreamcast/hardware/maple/mouse.c | 1 + kernel/arch/dreamcast/hardware/maple/sip.c | 1 + kernel/arch/dreamcast/hardware/maple/vmu.c | 1 + kernel/arch/dreamcast/hardware/sq.c | 67 +++++++-- kernel/arch/dreamcast/include/arch/arch.h | 15 ++- kernel/arch/dreamcast/include/dc/maple.h | 23 ++-- kernel/exports.txt | 11 ++ kernel/fs/fs_dev.c | 28 +++- kernel/fs/fs_null.c | 4 +- kernel/fs/fs_pty.c | 77 +++++++++-- kernel/fs/fs_ramdisk.c | 74 +++++----- kernel/fs/fs_random.c | 6 +- kernel/fs/fs_romdisk.c | 73 ++++++++-- kernel/fs/fs_utils.c | 11 +- kernel/libc/koslib/realpath.c | 11 +- kernel/thread/thread.c | 2 +- 31 files changed, 648 insertions(+), 355 deletions(-) diff --git a/addons/libkosext2fs/fs_ext2.c b/addons/libkosext2fs/fs_ext2.c index e3d004f0..a3388a54 100644 --- a/addons/libkosext2fs/fs_ext2.c +++ b/addons/libkosext2fs/fs_ext2.c @@ -1685,21 +1685,33 @@ static ssize_t fs_ext2_readlink(vfs_handler_t *vfs, const char *path, char *buf, return len; } -int fs_ext2_stat(vfs_handler_t *vfs, const char *path, struct stat *buf, +int fs_ext2_stat(vfs_handler_t *vfs, const char *path, struct stat *st, int flag) { - fs_ext2_fs_t *fs = (fs_ext2_fs_t *)vfs->privdata; int irv; ext2_inode_t *inode; uint32_t inode_num; int rl = 1; uint64_t sz; + size_t len = strlen(path); /* Do we want the status of a symlink or of the thing it points at if we end up with a symlink at the end of path resolution? */ if(flag & AT_SYMLINK_NOFOLLOW) rl = 2; + /* Root directory ext2 device */ + if(len == 0 || (len == 1 && *path == '/')) { + memset(st, 0, sizeof(struct stat)); + st->st_dev = (dev_t)((ptr_t)vfs); + st->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | + S_IXGRP | S_IXOTH | S_IWUSR | S_IWGRP | S_IWOTH; + st->st_size = -1; + st->st_nlink = 2; + + return 0; + } + mutex_lock(&ext2_mutex); /* Find the object in question */ @@ -1710,29 +1722,29 @@ int fs_ext2_stat(vfs_handler_t *vfs, const char *path, struct stat *buf, } /* Fill in the structure */ - memset(buf, 0, sizeof(struct stat)); - buf->st_dev = (dev_t)((ptr_t)vfs); - buf->st_ino = inode_num; - buf->st_mode = inode->i_mode & 0x0FFF; - buf->st_nlink = inode->i_links_count; - buf->st_uid = inode->i_uid; - buf->st_gid = inode->i_gid; - - buf->st_atime = inode->i_atime; - buf->st_mtime = inode->i_mtime; - buf->st_ctime = inode->i_ctime; - buf->st_blksize = 512; - buf->st_blocks = inode->i_blocks; + memset(st, 0, sizeof(struct stat)); + st->st_dev = (dev_t)((ptr_t)vfs); + st->st_ino = inode_num; + st->st_mode = inode->i_mode & 0x0FFF; + st->st_nlink = inode->i_links_count; + st->st_uid = inode->i_uid; + st->st_gid = inode->i_gid; + + st->st_atime = inode->i_atime; + st->st_mtime = inode->i_mtime; + st->st_ctime = inode->i_ctime; + st->st_blksize = 512; + st->st_blocks = inode->i_blocks; /* The rest depends on what type of inode this is... */ switch(inode->i_mode & 0xF000) { case EXT2_S_IFLNK: - buf->st_mode |= S_IFLNK; - buf->st_size = inode->i_size; + st->st_mode |= S_IFLNK; + st->st_size = inode->i_size; break; case EXT2_S_IFREG: - buf->st_mode |= S_IFREG; + st->st_mode |= S_IFREG; sz = ext2_inode_size(inode); if(sz > LONG_MAX) { @@ -1740,28 +1752,28 @@ int fs_ext2_stat(vfs_handler_t *vfs, const char *path, struct stat *buf, irv = -1; } - buf->st_size = sz; + st->st_size = sz; break; case EXT2_S_IFDIR: - buf->st_mode |= S_IFDIR; - buf->st_size = inode->i_size; + st->st_mode |= S_IFDIR; + st->st_size = inode->i_size; break; case EXT2_S_IFSOCK: - buf->st_mode |= S_IFSOCK; + st->st_mode |= S_IFSOCK; break; case EXT2_S_IFIFO: - buf->st_mode |= S_IFIFO; + st->st_mode |= S_IFIFO; break; case EXT2_S_IFBLK: - buf->st_mode |= S_IFBLK; + st->st_mode |= S_IFBLK; break; case EXT2_S_IFCHR: - buf->st_mode |= S_IFCHR; + st->st_mode |= S_IFCHR; break; } @@ -1790,7 +1802,7 @@ static int fs_ext2_rewinddir(void *h) { return 0; } -static int fs_ext2_fstat(void *h, struct stat *buf) { +static int fs_ext2_fstat(void *h, struct stat *st) { fs_ext2_fs_t *fs; ext2_inode_t *inode; uint64_t sz; @@ -1810,29 +1822,29 @@ static int fs_ext2_fstat(void *h, struct stat *buf) { fs = fh[fd].fs; /* Fill in the structure */ - memset(buf, 0, sizeof(struct stat)); - buf->st_dev = (dev_t)((ptr_t)fs->vfsh); - buf->st_ino = fh[fd].inode_num; - buf->st_mode = inode->i_mode & 0x0FFF; - buf->st_nlink = inode->i_links_count; - buf->st_uid = inode->i_uid; - buf->st_gid = inode->i_gid; - - buf->st_atime = inode->i_atime; - buf->st_mtime = inode->i_mtime; - buf->st_ctime = inode->i_ctime; - buf->st_blksize = 512; - buf->st_blocks = inode->i_blocks; + memset(st, 0, sizeof(struct stat)); + st->st_dev = (dev_t)((ptr_t)fs->vfsh); + st->st_ino = fh[fd].inode_num; + st->st_mode = inode->i_mode & 0x0FFF; + st->st_nlink = inode->i_links_count; + st->st_uid = inode->i_uid; + st->st_gid = inode->i_gid; + + st->st_atime = inode->i_atime; + st->st_mtime = inode->i_mtime; + st->st_ctime = inode->i_ctime; + st->st_blksize = 512; + st->st_blocks = inode->i_blocks; /* The rest depends on what type of inode this is... */ switch(inode->i_mode & 0xF000) { case EXT2_S_IFLNK: - buf->st_mode |= S_IFLNK; - buf->st_size = inode->i_size; + st->st_mode |= S_IFLNK; + st->st_size = inode->i_size; break; case EXT2_S_IFREG: - buf->st_mode |= S_IFREG; + st->st_mode |= S_IFREG; sz = ext2_inode_size(inode); if(sz > LONG_MAX) { @@ -1840,28 +1852,28 @@ static int fs_ext2_fstat(void *h, struct stat *buf) { irv = -1; } - buf->st_size = sz; + st->st_size = sz; break; case EXT2_S_IFDIR: - buf->st_mode |= S_IFDIR; - buf->st_size = inode->i_size; + st->st_mode |= S_IFDIR; + st->st_size = inode->i_size; break; case EXT2_S_IFSOCK: - buf->st_mode |= S_IFSOCK; + st->st_mode |= S_IFSOCK; break; case EXT2_S_IFIFO: - buf->st_mode |= S_IFIFO; + st->st_mode |= S_IFIFO; break; case EXT2_S_IFBLK: - buf->st_mode |= S_IFBLK; + st->st_mode |= S_IFBLK; break; case EXT2_S_IFCHR: - buf->st_mode |= S_IFCHR; + st->st_mode |= S_IFCHR; break; } diff --git a/addons/libkosfat/fs_fat.c b/addons/libkosfat/fs_fat.c index 55732379..636a7132 100644 --- a/addons/libkosfat/fs_fat.c +++ b/addons/libkosfat/fs_fat.c @@ -1038,16 +1038,29 @@ static int fs_fat_unlink(vfs_handler_t *vfs, const char *fn) { return irv; } -static int fs_fat_stat(vfs_handler_t *vfs, const char *path, struct stat *buf, +static int fs_fat_stat(vfs_handler_t *vfs, const char *path, struct stat *st, int flag) { fs_fat_fs_t *fs = (fs_fat_fs_t *)vfs->privdata; uint32_t sz, bs; int irv = 0; fat_dentry_t ent; uint32_t cl, off, lcl, loff; + size_t len = strlen(path); (void)flag; + /* Root directory fat device */ + if(len == 0 || (len == 1 && *path == '/')) { + memset(st, 0, sizeof(struct stat)); + st->st_dev = (dev_t)((ptr_t)fs->vfsh); + st->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | + S_IXGRP | S_IXOTH | S_IWUSR | S_IWGRP | S_IWOTH; + st->st_size = -1; + st->st_nlink = 2; + + return 0; + } + mutex_lock(&fat_mutex); /* Find the object in question */ @@ -1059,32 +1072,32 @@ static int fs_fat_stat(vfs_handler_t *vfs, const char *path, struct stat *buf, } /* Fill in the structure */ - memset(buf, 0, sizeof(struct stat)); + memset(st, 0, sizeof(struct stat)); irv = 0; - buf->st_dev = (dev_t)((ptr_t)fs->vfsh); - buf->st_ino = ent.cluster_low | (ent.cluster_high << 16); - buf->st_nlink = 1; - buf->st_uid = 0; - buf->st_gid = 0; - buf->st_blksize = fat_cluster_size(fs->fs); + st->st_dev = (dev_t)((ptr_t)fs->vfsh); + st->st_ino = ent.cluster_low | (ent.cluster_high << 16); + st->st_nlink = 1; + st->st_uid = 0; + st->st_gid = 0; + st->st_blksize = fat_cluster_size(fs->fs); /* Read the mode bits... */ - buf->st_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH; + st->st_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH; if(!(ent.attr & FAT_ATTR_READ_ONLY)) { - buf->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; + st->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; } /* Fill in the timestamps... */ - fill_stat_timestamps(&ent, buf); + fill_stat_timestamps(&ent, st); /* The rest depends on what type of object this is... */ if(ent.attr & FAT_ATTR_DIRECTORY) { - buf->st_mode |= S_IFDIR; - buf->st_size = 0; - buf->st_blocks = 0; + st->st_mode |= S_IFDIR; + st->st_size = 0; + st->st_blocks = 0; } else { - buf->st_mode |= S_IFREG; + st->st_mode |= S_IFREG; sz = ent.size; if(sz > LONG_MAX) { @@ -1092,12 +1105,12 @@ static int fs_fat_stat(vfs_handler_t *vfs, const char *path, struct stat *buf, irv = -1; } - buf->st_size = sz; + st->st_size = sz; bs = fat_cluster_size(fs->fs); - buf->st_blocks = sz / bs; + st->st_blocks = sz / bs; if(sz & (bs - 1)) - ++buf->st_blocks; + ++st->st_blocks; } mutex_unlock(&fat_mutex); diff --git a/examples/dreamcast/filesystem/browse/browse.c b/examples/dreamcast/filesystem/browse/browse.c index 80f681d6..ccd3bf29 100644 --- a/examples/dreamcast/filesystem/browse/browse.c +++ b/examples/dreamcast/filesystem/browse/browse.c @@ -268,7 +268,7 @@ static int browse_directory(char *directory, directory_file_t *directory_content /* Open the directory */ if (!(d = opendir(directory))) { - fprintf(stderr, "browse_directory: opendir failed\n"); + fprintf(stderr, "browse_directory: opendir failed for %s\n", directory); return 0; } diff --git a/kernel/arch/dreamcast/fs/fs_dcload.c b/kernel/arch/dreamcast/fs/fs_dcload.c index 891e6fa9..949952ab 100644 --- a/kernel/arch/dreamcast/fs/fs_dcload.c +++ b/kernel/arch/dreamcast/fs/fs_dcload.c @@ -364,9 +364,10 @@ int dcload_unlink(vfs_handler_t * vfs, const char *fn) { return ret; } -static int dcload_stat(vfs_handler_t *vfs, const char *fn, struct stat *rv, +static int dcload_stat(vfs_handler_t *vfs, const char *path, struct stat *st, int flag) { dcload_stat_t filestat; + size_t len = strlen(path); int retval; (void)flag; @@ -374,25 +375,36 @@ static int dcload_stat(vfs_handler_t *vfs, const char *fn, struct stat *rv, if(lwip_dclsc && irq_inside_int()) return 0; + /* Root directory '/pc' */ + if(len == 0 || (len == 1 && *path == '/')) { + memset(st, 0, sizeof(struct stat)); + st->st_dev = (dev_t)((ptr_t)vfs); + st->st_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO; + st->st_size = -1; + st->st_nlink = 2; + + return 0; + } + spinlock_lock(&mutex); - retval = dclsc(DCLOAD_STAT, fn, &filestat); + retval = dclsc(DCLOAD_STAT, path, &filestat); spinlock_unlock(&mutex); if(!retval) { - memset(rv, 0, sizeof(struct stat)); - rv->st_dev = (dev_t)((ptr_t)vfs); - rv->st_ino = filestat.st_ino; - rv->st_mode = filestat.st_mode; - rv->st_nlink = filestat.st_nlink; - rv->st_uid = filestat.st_uid; - rv->st_gid = filestat.st_gid; - rv->st_rdev = filestat.st_rdev; - rv->st_size = filestat.st_size; - rv->st_atime = filestat.atime; - rv->st_mtime = filestat.mtime; - rv->st_ctime = filestat.ctime; - rv->st_blksize = filestat.st_blksize; - rv->st_blocks = filestat.st_blocks; + memset(st, 0, sizeof(struct stat)); + st->st_dev = (dev_t)((ptr_t)vfs); + st->st_ino = filestat.st_ino; + st->st_mode = filestat.st_mode; + st->st_nlink = filestat.st_nlink; + st->st_uid = filestat.st_uid; + st->st_gid = filestat.st_gid; + st->st_rdev = filestat.st_rdev; + st->st_size = filestat.st_size; + st->st_atime = filestat.atime; + st->st_mtime = filestat.mtime; + st->st_ctime = filestat.ctime; + st->st_blksize = filestat.st_blksize; + st->st_blocks = filestat.st_blocks; return 0; } diff --git a/kernel/arch/dreamcast/fs/fs_iso9660.c b/kernel/arch/dreamcast/fs/fs_iso9660.c index 6f3f5273..03e2930a 100644 --- a/kernel/arch/dreamcast/fs/fs_iso9660.c +++ b/kernel/arch/dreamcast/fs/fs_iso9660.c @@ -968,6 +968,53 @@ static void iso_vblank(uint32 evt, void *data) { } } +static int iso_stat(vfs_handler_t *vfs, const char *path, struct stat *st, + int flag) { + mode_t md; + iso_dirent_t *de; + size_t len = strlen(path); + + (void)vfs; + (void)flag; + + /* Root directory of cd */ + if(len == 0 || (len == 1 && *path == '/')) { + memset(st, 0, sizeof(struct stat)); + st->st_dev = (dev_t)('c' | ('d' << 8)); + st->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | + S_IXGRP | S_IXOTH; + st->st_size = -1; + st->st_nlink = 2; + + return 0; + } + + /* First try opening as a file */ + de = find_object_path(path, 0, &root_dirent); + md = S_IFREG; + + /* If we couldn't get it as a file, try as a directory */ + if(!de) { + de = find_object_path(path, 1, &root_dirent); + md = S_IFDIR; + } + + /* If we still don't have it, then we're not going to get it. */ + if(!de) { + errno = ENOENT; + return -1; + } + + memset(st, 0, sizeof(struct stat)); + st->st_dev = (dev_t)('c' | ('d' << 8)); + st->st_mode = md | S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH; + st->st_size = (md == S_IFDIR) ? -1 : (int)iso_733(de->size); + st->st_nlink = (md == S_IFDIR) ? 2 : 1; + st->st_blksize = 512; + + return 0; +} + static int iso_fcntl(void *h, int cmd, va_list ap) { file_t fd = (file_t)h; int rv = -1; @@ -1010,23 +1057,12 @@ static int iso_fstat(void *h, struct stat *st) { } memset(st, 0, sizeof(struct stat)); - - if(fh[fd].dir) { - st->st_size = 0; - st->st_dev = 'c' | ('d' << 8); - st->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | - S_IXGRP | S_IXOTH; - st->st_nlink = 1; - st->st_blksize = 512; - } - else { - st->st_size = fh[fd].size; - st->st_dev = 'c' | ('d' << 8); - st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | - S_IXGRP | S_IXOTH; - st->st_nlink = 1; - st->st_blksize = 512; - } + st->st_dev = 'c' | ('d' << 8); + st->st_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH; + st->st_mode |= fh[fd].dir ? S_IFDIR : S_IFREG; + st->st_size = fh[fd].dir ? -1 : (int)fh[fd].size; + st->st_nlink = fh[fd].dir ? 2 : 1; + st->st_blksize = 512; return 0; ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |