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