|
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.
|