archive/romfs: Reduce TLS usage by sharing buffers + changed archive_rename to use a VLA

This commit is contained in:
fincs 2020-07-02 21:34:02 +02:00
parent 3e1d03aecd
commit 1c7914e2f4
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60
4 changed files with 57 additions and 50 deletions

View File

@ -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)

View 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];

View 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];

View File

@ -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)
{