archive/romfs: Reduce TLS usage by sharing buffers + changed archive_rename to use a VLA
This commit is contained in:
parent
3e1d03aecd
commit
1c7914e2f4
@ -14,6 +14,7 @@
|
||||
#include <3ds/services/fs.h>
|
||||
#include <3ds/util/utf.h>
|
||||
|
||||
#include "path_buf.h"
|
||||
|
||||
/*! @internal
|
||||
*
|
||||
@ -110,9 +111,6 @@ static archive_fsdevice archive_devices[32];
|
||||
|
||||
/*! @endcond */
|
||||
|
||||
static __thread char __fixedpath[PATH_MAX+1];
|
||||
static __thread uint16_t __utf16path[PATH_MAX+1];
|
||||
|
||||
static archive_fsdevice *archiveFindDevice(const char *name)
|
||||
{
|
||||
u32 i;
|
||||
@ -204,17 +202,17 @@ archive_fixpath(struct _reent *r,
|
||||
}
|
||||
|
||||
if(path[0] == '/')
|
||||
strncpy(__fixedpath, path, PATH_MAX);
|
||||
strncpy(__ctru_dev_path_buf, path, PATH_MAX);
|
||||
else
|
||||
{
|
||||
strncpy(__fixedpath, dev->cwd, PATH_MAX);
|
||||
__fixedpath[PATH_MAX] = '\0';
|
||||
strncat(__fixedpath, path, PATH_MAX);
|
||||
strncpy(__ctru_dev_path_buf, dev->cwd, PATH_MAX);
|
||||
__ctru_dev_path_buf[PATH_MAX] = '\0';
|
||||
strncat(__ctru_dev_path_buf, path, PATH_MAX);
|
||||
}
|
||||
|
||||
if(__fixedpath[PATH_MAX] != 0)
|
||||
if(__ctru_dev_path_buf[PATH_MAX] != 0)
|
||||
{
|
||||
__fixedpath[PATH_MAX] = 0;
|
||||
__ctru_dev_path_buf[PATH_MAX] = 0;
|
||||
r->_errno = ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
@ -222,7 +220,7 @@ archive_fixpath(struct _reent *r,
|
||||
if(device)
|
||||
*device = dev;
|
||||
|
||||
return __fixedpath;
|
||||
return __ctru_dev_path_buf;
|
||||
}
|
||||
|
||||
static const FS_Path
|
||||
@ -238,23 +236,23 @@ archive_utf16path(struct _reent *r,
|
||||
if(archive_fixpath(r, path, device) == NULL)
|
||||
return fspath;
|
||||
|
||||
units = utf8_to_utf16(__utf16path, (const uint8_t*)__fixedpath, PATH_MAX);
|
||||
units = utf8_to_utf16(__ctru_dev_utf16_buf, (const uint8_t*)__ctru_dev_path_buf, PATH_MAX);
|
||||
if(units < 0)
|
||||
{
|
||||
r->_errno = EILSEQ;
|
||||
return fspath;
|
||||
}
|
||||
if(units >= PATH_MAX)
|
||||
if(units > PATH_MAX)
|
||||
{
|
||||
r->_errno = ENAMETOOLONG;
|
||||
return fspath;
|
||||
}
|
||||
|
||||
__utf16path[units] = 0;
|
||||
__ctru_dev_utf16_buf[units] = 0;
|
||||
|
||||
fspath.type = PATH_UTF16;
|
||||
fspath.size = (units+1)*sizeof(uint16_t);
|
||||
fspath.data = (const u8*)__utf16path;
|
||||
fspath.data = __ctru_dev_utf16_buf;
|
||||
|
||||
return fspath;
|
||||
}
|
||||
@ -379,15 +377,15 @@ Result archiveMountSdmc(void)
|
||||
{
|
||||
if(FindDevice(__system_argv[0]) == rc)
|
||||
{
|
||||
strncpy(__fixedpath,__system_argv[0],PATH_MAX);
|
||||
if(__fixedpath[PATH_MAX] != 0)
|
||||
strncpy(__ctru_dev_path_buf,__system_argv[0],PATH_MAX);
|
||||
if(__ctru_dev_path_buf[PATH_MAX] != 0)
|
||||
{
|
||||
__fixedpath[PATH_MAX] = 0;
|
||||
__ctru_dev_path_buf[PATH_MAX] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *last_slash = NULL;
|
||||
p = __fixedpath;
|
||||
p = __ctru_dev_path_buf;
|
||||
do
|
||||
{
|
||||
units = decode_utf8(&code, (const uint8_t*)p);
|
||||
@ -406,7 +404,7 @@ Result archiveMountSdmc(void)
|
||||
if(last_slash != NULL)
|
||||
{
|
||||
last_slash[0] = 0;
|
||||
chdir(__fixedpath);
|
||||
chdir(__ctru_dev_path_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -927,7 +925,7 @@ archive_chdir(struct _reent *r,
|
||||
if(R_SUCCEEDED(rc))
|
||||
{
|
||||
FSDIR_Close(fd);
|
||||
strncpy(device->cwd, __fixedpath, PATH_MAX + 1);
|
||||
strncpy(device->cwd, __ctru_dev_path_buf, PATH_MAX + 1);
|
||||
device->cwd[PATH_MAX] = '\0';
|
||||
return 0;
|
||||
}
|
||||
@ -952,7 +950,6 @@ archive_rename(struct _reent *r,
|
||||
{
|
||||
Result rc;
|
||||
FS_Path fs_path_old, fs_path_new;
|
||||
static __thread uint16_t __utf16path_old[PATH_MAX+1];
|
||||
archive_fsdevice *sourceDevice = r->deviceData;
|
||||
archive_fsdevice *destDevice = NULL;
|
||||
|
||||
@ -967,8 +964,9 @@ archive_rename(struct _reent *r,
|
||||
if(fs_path_old.data == NULL)
|
||||
return -1;
|
||||
|
||||
memcpy(__utf16path_old, __utf16path, sizeof(__utf16path));
|
||||
fs_path_old.data = (const u8*)__utf16path_old;
|
||||
uint8_t old_path_copy[fs_path_old.size];
|
||||
memcpy(old_path_copy, fs_path_old.data, fs_path_old.size);
|
||||
fs_path_old.data = old_path_copy;
|
||||
|
||||
fs_path_new = archive_utf16path(r, newName, &destDevice);
|
||||
if(fs_path_new.data == NULL)
|
||||
|
4
libctru/source/path_buf.c
Normal file
4
libctru/source/path_buf.c
Normal file
@ -0,0 +1,4 @@
|
||||
#include "path_buf.h"
|
||||
|
||||
char __thread __ctru_dev_path_buf[PATH_MAX+1];
|
||||
uint16_t __thread __ctru_dev_utf16_buf[PATH_MAX+1];
|
6
libctru/source/path_buf.h
Normal file
6
libctru/source/path_buf.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
extern char __thread __ctru_dev_path_buf[PATH_MAX+1];
|
||||
extern uint16_t __thread __ctru_dev_utf16_buf[PATH_MAX+1];
|
@ -16,6 +16,8 @@
|
||||
#include <3ds/util/utf.h>
|
||||
#include <3ds/env.h>
|
||||
|
||||
#include "path_buf.h"
|
||||
|
||||
typedef struct romfs_mount
|
||||
{
|
||||
Handle fd;
|
||||
@ -31,9 +33,6 @@ typedef struct romfs_mount
|
||||
extern int __system_argc;
|
||||
extern char** __system_argv;
|
||||
|
||||
static char __component[PATH_MAX+1];
|
||||
static uint16_t __utf16path[PATH_MAX+1];
|
||||
|
||||
#define romFS_root(m) ((romfs_dir*)(m)->dirTable)
|
||||
#define romFS_dir(m,x) ((romfs_dir*) ((u8*)(m)->dirTable + (x)))
|
||||
#define romFS_file(m,x) ((romfs_file*)((u8*)(m)->fileTable + (x)))
|
||||
@ -192,10 +191,10 @@ Result romfsMount(struct romfs_mount **p)
|
||||
filename += 5;
|
||||
else if (strncmp(filename, "3dslink:/", 9) == 0)
|
||||
{
|
||||
strncpy(__component, "/3ds", PATH_MAX);
|
||||
strncat(__component, filename+8, PATH_MAX);
|
||||
__component[PATH_MAX] = 0;
|
||||
filename = __component;
|
||||
strncpy(__ctru_dev_path_buf, "/3ds", PATH_MAX);
|
||||
strncat(__ctru_dev_path_buf, filename+8, PATH_MAX);
|
||||
__ctru_dev_path_buf[PATH_MAX] = 0;
|
||||
filename = __ctru_dev_path_buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -203,21 +202,21 @@ Result romfsMount(struct romfs_mount **p)
|
||||
return 2;
|
||||
}
|
||||
|
||||
ssize_t units = utf8_to_utf16(__utf16path, (const uint8_t*)filename, PATH_MAX);
|
||||
ssize_t units = utf8_to_utf16(__ctru_dev_utf16_buf, (const uint8_t*)filename, PATH_MAX);
|
||||
if (units < 0)
|
||||
{
|
||||
romfs_free(mount);
|
||||
return 3;
|
||||
}
|
||||
if (units >= PATH_MAX)
|
||||
if (units > PATH_MAX)
|
||||
{
|
||||
romfs_free(mount);
|
||||
return 4;
|
||||
}
|
||||
__utf16path[units] = 0;
|
||||
__ctru_dev_utf16_buf[units] = 0;
|
||||
|
||||
FS_Path archPath = { PATH_EMPTY, 1, "" };
|
||||
FS_Path filePath = { PATH_UTF16, (units+1)*2, __utf16path };
|
||||
FS_Path filePath = { PATH_UTF16, (units+1)*2, __ctru_dev_utf16_buf };
|
||||
|
||||
Result rc = FSUSER_OpenFileDirectly(&mount->fd, ARCHIVE_SDMC, archPath, filePath, FS_OPEN_READ, 0);
|
||||
if (R_FAILED(rc))
|
||||
@ -456,7 +455,7 @@ static int navigateToDir(romfs_mount *mount, romfs_dir** ppDir, const char** pPa
|
||||
while (**pPath)
|
||||
{
|
||||
char* slashPos = strchr(*pPath, '/');
|
||||
char* component = __component;
|
||||
char* component = __ctru_dev_path_buf;
|
||||
|
||||
if (slashPos)
|
||||
{
|
||||
@ -486,13 +485,13 @@ static int navigateToDir(romfs_mount *mount, romfs_dir** ppDir, const char** pPa
|
||||
}
|
||||
}
|
||||
|
||||
units = utf8_to_utf16(__utf16path, (const uint8_t*)component, PATH_MAX);
|
||||
units = utf8_to_utf16(__ctru_dev_utf16_buf, (const uint8_t*)component, PATH_MAX);
|
||||
if (units < 0)
|
||||
return EILSEQ;
|
||||
if (units >= PATH_MAX)
|
||||
if (units > PATH_MAX)
|
||||
return ENAMETOOLONG;
|
||||
|
||||
*ppDir = searchForDir(mount, *ppDir, __utf16path, units);
|
||||
*ppDir = searchForDir(mount, *ppDir, __ctru_dev_utf16_buf, units);
|
||||
if (!*ppDir)
|
||||
return ENOENT;
|
||||
}
|
||||
@ -581,7 +580,7 @@ int romfs_open(struct _reent *r, void *fileStruct, const char *path, int flags,
|
||||
if (r->_errno != 0)
|
||||
return -1;
|
||||
|
||||
ssize_t units = utf8_to_utf16(__utf16path, (const uint8_t*)path, PATH_MAX);
|
||||
ssize_t units = utf8_to_utf16(__ctru_dev_utf16_buf, (const uint8_t*)path, PATH_MAX);
|
||||
if (units <= 0)
|
||||
{
|
||||
r->_errno = EILSEQ;
|
||||
@ -593,7 +592,7 @@ int romfs_open(struct _reent *r, void *fileStruct, const char *path, int flags,
|
||||
return -1;
|
||||
}
|
||||
|
||||
romfs_file* file = searchForFile(fileobj->mount, curDir, __utf16path, units);
|
||||
romfs_file* file = searchForFile(fileobj->mount, curDir, __ctru_dev_utf16_buf, units);
|
||||
if (!file)
|
||||
{
|
||||
if(flags & O_CREAT)
|
||||
@ -709,26 +708,26 @@ int romfs_stat(struct _reent *r, const char *path, struct stat *st)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t units = utf8_to_utf16(__utf16path, (const uint8_t*)path, PATH_MAX);
|
||||
ssize_t units = utf8_to_utf16(__ctru_dev_utf16_buf, (const uint8_t*)path, PATH_MAX);
|
||||
if (units <= 0)
|
||||
{
|
||||
r->_errno = EILSEQ;
|
||||
return -1;
|
||||
}
|
||||
if (units >= PATH_MAX)
|
||||
if (units > PATH_MAX)
|
||||
{
|
||||
r->_errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
romfs_dir* dir = searchForDir(mount, curDir, __utf16path, units);
|
||||
romfs_dir* dir = searchForDir(mount, curDir, __ctru_dev_utf16_buf, units);
|
||||
if(dir)
|
||||
{
|
||||
fill_dir(st, mount, dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
romfs_file* file = searchForFile(mount, curDir, __utf16path, units);
|
||||
romfs_file* file = searchForFile(mount, curDir, __ctru_dev_utf16_buf, units);
|
||||
if(file)
|
||||
{
|
||||
fill_file(st, mount, file);
|
||||
@ -821,9 +820,9 @@ int romfs_dirnext(struct _reent *r, DIR_ITER *dirState, char *filename, struct s
|
||||
|
||||
/* convert name from UTF-16 to UTF-8 */
|
||||
memset(filename, 0, NAME_MAX);
|
||||
memcpy(__utf16path, dir->name, dir->nameLen*sizeof(uint16_t));
|
||||
__utf16path[dir->nameLen/sizeof(uint16_t)] = 0;
|
||||
units = utf16_to_utf8((uint8_t*)filename, __utf16path, NAME_MAX);
|
||||
memcpy(__ctru_dev_utf16_buf, dir->name, dir->nameLen*sizeof(uint16_t));
|
||||
__ctru_dev_utf16_buf[dir->nameLen/sizeof(uint16_t)] = 0;
|
||||
units = utf16_to_utf8((uint8_t*)filename, __ctru_dev_utf16_buf, NAME_MAX);
|
||||
|
||||
if(units < 0)
|
||||
{
|
||||
@ -852,9 +851,9 @@ int romfs_dirnext(struct _reent *r, DIR_ITER *dirState, char *filename, struct s
|
||||
|
||||
/* convert name from UTF-16 to UTF-8 */
|
||||
memset(filename, 0, NAME_MAX);
|
||||
memcpy(__utf16path, file->name, file->nameLen*sizeof(uint16_t));
|
||||
__utf16path[file->nameLen/sizeof(uint16_t)] = 0;
|
||||
units = utf16_to_utf8((uint8_t*)filename, __utf16path, NAME_MAX);
|
||||
memcpy(__ctru_dev_utf16_buf, file->name, file->nameLen*sizeof(uint16_t));
|
||||
__ctru_dev_utf16_buf[file->nameLen/sizeof(uint16_t)] = 0;
|
||||
units = utf16_to_utf8((uint8_t*)filename, __ctru_dev_utf16_buf, NAME_MAX);
|
||||
|
||||
if(units < 0)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user