From: Lawrence S. <ljs...@us...> - 2014-11-03 14:49:06
|
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 eea75bfaa47996beccc876322697a73c6b86772a (commit) from 96a6132ad5b34d153d537b728869590e26f0a46c (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 eea75bfaa47996beccc876322697a73c6b86772a Author: Lawrence Sebald <ljs...@us...> Date: Mon Nov 3 09:48:28 2014 -0500 Add rewinddir(). ----------------------------------------------------------------------- Summary of changes: addons/libkosext2fs/fs_ext2.c | 32 +++++++++++++++++++++++----- include/kos/fs.h | 17 +++++++++++++++ kernel/arch/dreamcast/fs/fs_dcload.c | 3 +- kernel/arch/dreamcast/fs/fs_dclsocket.c | 3 +- kernel/arch/dreamcast/fs/fs_iso9660.c | 19 +++++++++++++++- kernel/arch/dreamcast/fs/fs_vmu.c | 22 +++++++++++++++++++- kernel/fs/fs.c | 24 ++++++++++++++++++++- kernel/fs/fs_pty.c | 21 +++++++++++++++++- kernel/fs/fs_ramdisk.c | 25 +++++++++++++++++++++- kernel/fs/fs_romdisk.c | 34 +++++++++++++++++++++++------- kernel/libc/koslib/rewinddir.c | 17 +++++++++++---- 11 files changed, 187 insertions(+), 30 deletions(-) diff --git a/addons/libkosext2fs/fs_ext2.c b/addons/libkosext2fs/fs_ext2.c index 4c14c72..30733a5 100644 --- a/addons/libkosext2fs/fs_ext2.c +++ b/addons/libkosext2fs/fs_ext2.c @@ -1,7 +1,7 @@ /* KallistiOS ##version## fs_ext2.c - Copyright (C) 2012, 2013 Lawrence Sebald + Copyright (C) 2012, 2013, 2014 Lawrence Sebald */ #include <time.h> @@ -293,7 +293,7 @@ static ssize_t fs_ext2_read(void *h, void *buf, size_t cnt) { mutex_unlock(&ext2_mutex); return -1; } - + if(cnt > bs - bo) { memcpy(bbuf, block + bo, bs - bo); fh[fd].ptr += bs - bo; @@ -614,7 +614,7 @@ retry: errno = EIO; return NULL; } - + /* Fill in the static directory entry. */ fh[fd].dent.size = inode->i_size; memcpy(fh[fd].dent.name, dent->name, dent->name_len); @@ -1071,7 +1071,7 @@ static int fs_ext2_unlink(vfs_handler_t *vfs, const char *fn) { /* And, we're done. Unlock the mutex. */ mutex_unlock(&ext2_mutex); - return 0; + return 0; } static int fs_ext2_mkdir(vfs_handler_t *vfs, const char *fn) { @@ -1430,7 +1430,7 @@ static int fs_ext2_link(vfs_handler_t *vfs, const char *path1, errno = -rv; return -1; } - + /* If the entry we get back is not a directory, then we've got problems. */ if((pinode->i_mode & 0xF000) != EXT2_S_IFDIR) { ext2_inode_put(pinode); @@ -1764,6 +1764,25 @@ int fs_ext2_stat(vfs_handler_t *vfs, const char *path, struct stat *buf, return irv; } +static int fs_ext2_rewinddir(void *h) { + file_t fd = ((file_t)h) - 1; + + mutex_lock(&ext2_mutex); + + /* Check that the fd is valid */ + if(fd >= MAX_EXT2_FILES || !fh[fd].inode_num || !(fh[fd].mode & O_DIR)) { + mutex_unlock(&ext2_mutex); + errno = EBADF; + return -1; + } + + /* Rewind to the beginning of the directory. */ + fh[fd].ptr = 0; + + mutex_unlock(&ext2_mutex); + return 0; +} + /* This is a template that will be used for each mount */ static vfs_handler_t vh = { /* Name Handler */ @@ -1801,7 +1820,8 @@ static vfs_handler_t vh = { fs_ext2_seek64, /* seek64 */ fs_ext2_tell64, /* tell64 */ fs_ext2_total64, /* total64 */ - fs_ext2_readlink /* readlink */ + fs_ext2_readlink, /* readlink */ + fs_ext2_rewinddir /* rewinddir */ }; static int initted = 0; diff --git a/include/kos/fs.h b/include/kos/fs.h index 96129cd..ea9dacf 100644 --- a/include/kos/fs.h +++ b/include/kos/fs.h @@ -190,6 +190,9 @@ typedef struct vfs_handler { possible that realpath() will call this function. */ ssize_t (*readlink)(struct vfs_handler *vfs, const char *path, char *buf, size_t bufsize); + + /** \brief Rewind a directory stream to the start */ + int (*rewinddir)(void *hnd); } vfs_handler_t; /** \brief The number of distinct file descriptors that can be in use at a @@ -543,6 +546,20 @@ ssize_t fs_readlink(const char *path, char *buf, size_t bufsize); */ int fs_stat(const char *path, struct stat *buf, int flag); +/** \brief Rewind a directory to the start. + + This function rewinds the position of a directory stream to the beginning of + the directory. + + \param hnd The opened directory's file descriptor. + \return 0 on success, -1 on failure. + + \note Some filesystems may not support this function. If a + filesystem doesn't support it, errno will be set to + ENOSYS and -1 will be returned. +*/ +int fs_rewinddir(file_t hnd); + /** \brief Duplicate a file descriptor. This function duplicates the specified file descriptor, returning a new file diff --git a/kernel/arch/dreamcast/fs/fs_dcload.c b/kernel/arch/dreamcast/fs/fs_dcload.c index c7afd94..48cc20a 100644 --- a/kernel/arch/dreamcast/fs/fs_dcload.c +++ b/kernel/arch/dreamcast/fs/fs_dcload.c @@ -460,7 +460,8 @@ static vfs_handler_t vh = { NULL, /* seek64 */ NULL, /* tell64 */ NULL, /* total64 */ - NULL /* readlink */ + NULL, /* readlink */ + NULL /* rewinddir */ }; // We have to provide a minimal interface in case dcload usage is diff --git a/kernel/arch/dreamcast/fs/fs_dclsocket.c b/kernel/arch/dreamcast/fs/fs_dclsocket.c index 28948d1..70d9bb1 100644 --- a/kernel/arch/dreamcast/fs/fs_dclsocket.c +++ b/kernel/arch/dreamcast/fs/fs_dclsocket.c @@ -726,7 +726,8 @@ static vfs_handler_t vh = { NULL, /* seek64 */ NULL, /* tell64 */ NULL, /* total64 */ - NULL /* readlink */ + NULL, /* readlink */ + NULL /* rewinddir */ }; /* dbgio handler */ diff --git a/kernel/arch/dreamcast/fs/fs_iso9660.c b/kernel/arch/dreamcast/fs/fs_iso9660.c index cf8b5cd..b8f1de6 100644 --- a/kernel/arch/dreamcast/fs/fs_iso9660.c +++ b/kernel/arch/dreamcast/fs/fs_iso9660.c @@ -4,7 +4,7 @@ Copyright (C) 2000, 2001, 2003 Dan Potter Copyright (C) 2001 Andrew Kieschnick Copyright (C) 2002 Bero - Copyright (C) 2012, 2013 Lawrence Sebald + Copyright (C) 2012, 2013, 2014 Lawrence Sebald */ @@ -900,6 +900,20 @@ static dirent_t *iso_readdir(void * h) { return &fh[fd].dirent; } +static int iso_rewinddir(void * h) { + file_t fd = (file_t)h; + + if(fd >= MAX_ISO_FILES || fh[fd].first_extent == 0 || !fh[fd].dir || + fh[fd].broken) { + errno = EBADF; + return -1; + } + + /* Rewind to the beginning of the directory. */ + fh[fd].ptr = 0; + return 0; +} + int iso_reset() { iso_break_all(); bclear(); @@ -1013,7 +1027,8 @@ static vfs_handler_t vh = { NULL, /* seek64 */ NULL, /* tell64 */ NULL, /* total64 */ - NULL /* readlink */ + NULL, /* readlink */ + iso_rewinddir }; /* Initialize the file system */ diff --git a/kernel/arch/dreamcast/fs/fs_vmu.c b/kernel/arch/dreamcast/fs/fs_vmu.c index 7bd69ff..e49ca9d 100644 --- a/kernel/arch/dreamcast/fs/fs_vmu.c +++ b/kernel/arch/dreamcast/fs/fs_vmu.c @@ -633,6 +633,25 @@ static int vmu_fcntl(void *fd, int cmd, va_list ap) { return rv; } +static int vmu_rewinddir(void * fd) { + vmu_dh_t *dh; + + /* Check the handle */ + if(!vmu_verify_hnd(fd, VMU_DIR)) { + errno = EBADF; + return -1; + } + + /* Rewind to the beginning of the directory. */ + dh = (vmu_dh_t*)fd; + dh->entry = 0; + + /* TODO: Technically, we need to re-scan the directory here, but for now we + will punt on that requirement. */ + + return 0; +} + /* handler interface */ static vfs_handler_t vh = { /* Name handler */ @@ -669,7 +688,8 @@ static vfs_handler_t vh = { NULL, /* seek64 */ NULL, /* tell64 */ NULL, /* total64 */ - NULL /* readlink */ + NULL, /* readlink */ + vmu_rewinddir }; int fs_vmu_init() { diff --git a/kernel/fs/fs.c b/kernel/fs/fs.c index f9216ed..caa3886 100644 --- a/kernel/fs/fs.c +++ b/kernel/fs/fs.c @@ -2,7 +2,7 @@ fs.c Copyright (C) 2000, 2001, 2002, 2003 Dan Potter - Copyright (C) 2012, 2013 Lawrence Sebald + Copyright (C) 2012, 2013, 2014 Lawrence Sebald */ @@ -523,7 +523,6 @@ dirent_t *fs_readdir(file_t fd) { return NULL; } - errno = 0; return h->handler->readdir(h->hnd); } @@ -851,6 +850,27 @@ int fs_stat(const char *path, struct stat *buf, int flag) { } } +int fs_rewinddir(file_t fd) { + fs_hnd_t *h = fs_map_hnd(fd); + + if(!h) { + errno = EBADF; + return -1; + } + + if(h->handler == NULL) { + h->hnd = (void *)0; + return 0; + } + + if(h->handler->rewinddir == NULL) { + errno = ENOSYS; + return -1; + } + + return h->handler->rewinddir(h->hnd); +} + /* Initialize FS structures */ int fs_init() { return 0; diff --git a/kernel/fs/fs_pty.c b/kernel/fs/fs_pty.c index 33d8387..8239d41 100644 --- a/kernel/fs/fs_pty.c +++ b/kernel/fs/fs_pty.c @@ -2,7 +2,7 @@ fs_pty.c Copyright (C) 2003 Dan Potter - Copyright (C) 2012 Lawrence Sebald + Copyright (C) 2012, 2014 Lawrence Sebald */ @@ -639,6 +639,22 @@ static dirent_t * pty_readdir(void * h) { return &dl->dirent; } +static int pty_rewinddir(void *h) { + pipefd_t *fdobj = (pipefd_t *)h; + dirlist_t *dl; + + assert(h); + + if(fdobj->type != PF_DIR) { + errno = EBADF; + return -1; + } + + dl = fdobj->d.d; + dl->ptr = 0; + return 0; +} + static int pty_fcntl(void *h, int cmd, va_list ap) { pipefd_t *fd = (pipefd_t *)h; int rv = -1; @@ -713,7 +729,8 @@ static vfs_handler_t vh = { NULL, NULL, NULL, - NULL + NULL, + pty_rewinddir }; /* Are we initialized? */ diff --git a/kernel/fs/fs_ramdisk.c b/kernel/fs/fs_ramdisk.c index b661c4a..af67bfc 100644 --- a/kernel/fs/fs_ramdisk.c +++ b/kernel/fs/fs_ramdisk.c @@ -2,7 +2,7 @@ fs_ramdisk.c Copyright (C) 2002, 2003 Dan Potter - Copyright (C) 2012, 2013 Lawrence Sebald + Copyright (C) 2012, 2013, 2014 Lawrence Sebald */ @@ -676,6 +676,26 @@ static int ramdisk_fcntl(void *h, int cmd, va_list ap) { return rv; } +static int ramdisk_rewinddir(void * h) { + int rv = 0; + file_t fd = (file_t)h; + + mutex_lock(&rd_mutex); + + if(fd >= MAX_RAM_FILES || !fh[fd].file || !fh[fd].dir) { + errno = EBADF; + rv = -1; + } + else { + /* Rewind to the first file. */ + fh[fd].ptr = (uint32)LIST_FIRST((rd_dir_t *)fh[fd].file->data); + } + + mutex_unlock(&rd_mutex); + + return rv; +} + /* Put everything together */ static vfs_handler_t vh = { /* Name handler */ @@ -713,7 +733,8 @@ static vfs_handler_t vh = { NULL, /* seek64 XXX */ NULL, /* tell64 XXX */ NULL, /* total64 XXX */ - NULL /* readlink XXX */ + NULL, /* readlink XXX */ + ramdisk_rewinddir }; /* Attach a piece of memory to a file. This works somewhat like open for diff --git a/kernel/fs/fs_romdisk.c b/kernel/fs/fs_romdisk.c index 7acbc4b..5eeaed8 100644 --- a/kernel/fs/fs_romdisk.c +++ b/kernel/fs/fs_romdisk.c @@ -2,7 +2,7 @@ fs_romdisk.c Copyright (C) 2001, 2002, 2003 Dan Potter - Copyright (C) 2012, 2013 Lawrence Sebald + Copyright (C) 2012, 2013, 2014 Lawrence Sebald */ @@ -349,15 +349,20 @@ static size_t romdisk_total(void * h) { /* Read a directory entry */ static dirent_t *romdisk_readdir(void * h) { - romdisk_file_t *fhdr; - int type; - file_t fd = (file_t)h; + romdisk_file_t *fhdr; + int type; + file_t fd = (file_t)h; if(fd >= MAX_RD_FILES || fh[fd].index == 0 || !fh[fd].dir) { errno = EBADF; return NULL; } + /* This happens if we hit the end of the directory on advancing the pointer + last time through. */ + if(fh[fd].ptr == (uint32)-1) + return NULL; + /* Get the current file header */ fhdr = (romdisk_file_t *)(fh[fd].mnt->image + fh[fd].index + fh[fd].ptr); @@ -366,10 +371,10 @@ static dirent_t *romdisk_readdir(void * h) { type = fh[fd].ptr & 0x0f; fh[fd].ptr = fh[fd].ptr & 0xfffffff0; - if(fh[fd].ptr == 0) - fh[fd].index = 0; - else + if(fh[fd].ptr != 0) fh[fd].ptr = fh[fd].ptr - fh[fd].index; + else + fh[fd].ptr = (uint32)-1; /* Copy out the requested data */ strcpy(fh[fd].dirent.name, fhdr->filename); @@ -432,6 +437,18 @@ static int romdisk_fcntl(void *h, int cmd, va_list ap) { return rv; } +static int romdisk_rewinddir(void *h) { + file_t fd = (file_t)h; + + if(fd >= MAX_RD_FILES || fh[fd].index == 0 || !fh[fd].dir) { + errno = EBADF; + return -1; + } + + fh[fd].ptr = 0; + return 0; +} + /* This is a template that will be used for each mount */ static vfs_handler_t vh = { /* Name Handler */ @@ -469,7 +486,8 @@ static vfs_handler_t vh = { NULL, /* seek64 */ NULL, /* tell64 */ NULL, /* total64 */ - NULL /* readlink */ + NULL, /* readlink */ + romdisk_rewinddir }; /* Are we initialized? */ diff --git a/kernel/libc/koslib/rewinddir.c b/kernel/libc/koslib/rewinddir.c index f30a5fa..3fa37c9 100644 --- a/kernel/libc/koslib/rewinddir.c +++ b/kernel/libc/koslib/rewinddir.c @@ -1,13 +1,20 @@ /* KallistiOS ##version## rewinddir.c - Copyright (C)2004 Dan Potter + Copyright (C) 2004 Dan Potter + Copyright (C) 2014 Lawrence Sebald */ -#include <kos/dbglog.h> +#include <dirent.h> +#include <errno.h> +#include <kos/fs.h> -// This isn't properly prototyped... sosume :) -void rewinddir() { - dbglog(DBG_WARNING, "rewinddir: call ignored\n"); +void rewinddir(DIR *dirp) { + if(!dirp) { + errno = EBADF; + return; + } + + (void)fs_rewinddir(dirp->fd); } hooks/post-receive -- A pseudo Operating System for the Dreamcast. |