implement chdir & relative path support

This commit is contained in:
Dave Murphy 2014-12-04 00:29:35 +00:00
parent 7c13463969
commit 1bc0073bd3

View File

@ -1,7 +1,10 @@
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <limits.h>
#include <sys/iosupport.h> #include <sys/iosupport.h>
#include <sys/param.h>
#include <string.h> #include <string.h>
#include <3ds.h> #include <3ds.h>
@ -96,14 +99,60 @@ static FS_archive sdmcArchive =
/*! @endcond */ /*! @endcond */
static char __cwd[PATH_MAX+1] = "/";
static char __fixedpath[PATH_MAX+1];
static const char *sdmc_fixpath(const char *path)
{
// Move the path pointer to the start of the actual path
if (strchr (path, ':') != NULL)
{
path = strchr (path, ':') + 1;
}
if (strchr (path, ':') != NULL) return NULL;
if (path[0]=='/') return path;
strncpy(__fixedpath,__cwd,PATH_MAX);
strncat(__fixedpath,path,PATH_MAX);
__fixedpath[PATH_MAX] = 0;
return __fixedpath;
}
int __system_argc;
char** __system_argv;
/*! Initialize SDMC device */ /*! Initialize SDMC device */
Result sdmcInit(void) Result sdmcInit(void)
{ {
Result rc; Result rc;
rc = FSUSER_OpenArchive(NULL, &sdmcArchive); rc = FSUSER_OpenArchive(NULL, &sdmcArchive);
if(rc == 0) if(rc == 0)
AddDevice(&sdmc_devoptab); {
int dev = AddDevice(&sdmc_devoptab);
if (__system_argc != 0 && __system_argv[0] != NULL)
{
if (FindDevice(__system_argv[0]) == dev)
{
strncpy(__fixedpath,__system_argv[0],PATH_MAX);
char *last_slash = strrchr(__fixedpath,'/');
if (last_slash != NULL) {
last_slash[0] = 0;
chdir(__fixedpath);
}
}
}
}
return rc; return rc;
} }
@ -142,10 +191,15 @@ sdmc_open(struct _reent *r,
Result rc; Result rc;
u32 sdmc_flags = 0; u32 sdmc_flags = 0;
u32 attributes = FS_ATTRIBUTE_NONE; u32 attributes = FS_ATTRIBUTE_NONE;
char *pathptr = NULL; const char *pathptr = NULL;
pathptr = strchr(path, '/'); pathptr = sdmc_fixpath(path);
if(pathptr==NULL)pathptr = (char*)path;
if(pathptr==NULL)
{
r->_errno=EINVAL;
return -1;
}
/* get pointer to our data */ /* get pointer to our data */
sdmc_file_t *file = (sdmc_file_t*)fileStruct; sdmc_file_t *file = (sdmc_file_t*)fileStruct;
@ -484,8 +538,32 @@ static int
sdmc_chdir(struct _reent *r, sdmc_chdir(struct _reent *r,
const char *name) const char *name)
{ {
r->_errno = ENOSYS; Handle fd;
return -1; Result rc;
const char *pathptr = NULL;
pathptr = sdmc_fixpath(name);
if(pathptr==NULL)
{
r->_errno=EINVAL;
return -1;
}
rc = FSUSER_OpenDirectory(NULL, &fd, sdmcArchive, FS_makePath(PATH_CHAR, pathptr));
if(rc == 0)
{
FSDIR_Close(fd);
strncpy(__cwd,pathptr,PATH_MAX);
}
else
{
r->_errno=EINVAL;
return -1;
}
return 0;
} }
/*! Rename a file /*! Rename a file
@ -521,10 +599,15 @@ sdmc_mkdir(struct _reent *r,
int mode) int mode)
{ {
Result rc; Result rc;
char *pathptr = NULL; const char *pathptr = NULL;
pathptr = strchr(path, '/'); pathptr = sdmc_fixpath(path);
if(pathptr==NULL)pathptr = (char*)path;
if(pathptr==NULL)
{
r->_errno=EINVAL;
return -1;
}
/* TODO: Use mode to set directory attributes. */ /* TODO: Use mode to set directory attributes. */
@ -552,10 +635,15 @@ sdmc_diropen(struct _reent *r,
{ {
Handle fd; Handle fd;
Result rc; Result rc;
char *pathptr = NULL; const char *pathptr = NULL;
pathptr = strchr(path, '/'); pathptr = sdmc_fixpath(path);
if(pathptr==NULL)pathptr = (char*)path;
if(pathptr==NULL)
{
r->_errno=EINVAL;
return NULL;
}
/* get pointer to our data */ /* get pointer to our data */
sdmc_dir_t *dir = (sdmc_dir_t*)(dirState->dirStruct); sdmc_dir_t *dir = (sdmc_dir_t*)(dirState->dirStruct);
@ -685,7 +773,7 @@ sdmc_statvfs(struct _reent *r,
{ {
Result rc; Result rc;
u32 clusterSize, numClusters, freeClusters; u32 clusterSize, numClusters, freeClusters;
u32 writable = 0; u8 writable = 0;
rc = FSUSER_GetSdmcArchiveResource(NULL, rc = FSUSER_GetSdmcArchiveResource(NULL,
NULL, NULL,
@ -787,7 +875,7 @@ sdmc_fsync(struct _reent *r,
* @returns 0 for success * @returns 0 for success
* @returns -1 for error * @returns -1 for error
*/ */
static int static int
sdmc_chmod(struct _reent *r, sdmc_chmod(struct _reent *r,
const char *path, const char *path,
mode_t mode) mode_t mode)