create a single fetchfs backend instead of 1 per file
symlinking manifest entries and using a baseurl gives us a way to create just a single fetchfs backend (and a single thread) since emscripten upstream is not willing to integrate manifest support to fetchfs directly. Retroarch embedders could use this to get assets or other resources lazily or chunk-by-chunk for large files.
This commit is contained in:
parent
9e64cce10f
commit
809e5d78be
|
@ -491,6 +491,7 @@ void platform_emscripten_mount_filesystems(void)
|
||||||
{
|
{
|
||||||
char *opfs_mount = getenv("OPFS_MOUNT");
|
char *opfs_mount = getenv("OPFS_MOUNT");
|
||||||
char *fetch_manifest = getenv("FETCH_MANIFEST");
|
char *fetch_manifest = getenv("FETCH_MANIFEST");
|
||||||
|
char *fetch_base_dir = getenv("FETCH_BASE_DIR");
|
||||||
if (opfs_mount)
|
if (opfs_mount)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
@ -518,20 +519,23 @@ void platform_emscripten_mount_filesystems(void)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fetch_manifest || fetch_base_dir)
|
||||||
if (fetch_manifest)
|
|
||||||
{
|
{
|
||||||
/* fetch_manifest should be a path to a manifest file.
|
/* fetch_manifest should be a path to a manifest file.
|
||||||
manifest files have this format:
|
manifest files have this format:
|
||||||
|
|
||||||
|
BASEURL
|
||||||
URL PATH
|
URL PATH
|
||||||
URL PATH
|
URL PATH
|
||||||
URL PATH
|
URL PATH
|
||||||
...
|
...
|
||||||
|
|
||||||
Where URL may not contain spaces, but PATH may.
|
Where URL may not contain spaces, but PATH may.
|
||||||
|
URL segments are relative to BASEURL.
|
||||||
*/
|
*/
|
||||||
int max_line_len = 1024;
|
int max_line_len = 1024;
|
||||||
|
if (!(fetch_manifest && fetch_base_dir))
|
||||||
|
printf("[FetchFS] must specify both FETCH_MANIFEST and FETCH_BASE_DIR\n");
|
||||||
printf("[FetchFS] read fetch manifest from %s\n", fetch_manifest);
|
printf("[FetchFS] read fetch manifest from %s\n", fetch_manifest);
|
||||||
FILE *file = fopen(fetch_manifest, "r");
|
FILE *file = fopen(fetch_manifest, "r");
|
||||||
if (!file)
|
if (!file)
|
||||||
|
@ -541,44 +545,66 @@ void platform_emscripten_mount_filesystems(void)
|
||||||
}
|
}
|
||||||
char *line = calloc(sizeof(char), max_line_len);
|
char *line = calloc(sizeof(char), max_line_len);
|
||||||
size_t len = max_line_len;
|
size_t len = max_line_len;
|
||||||
while (getline(&line, &len, file) != -1)
|
if (getline(&line, &len, file) == -1 || len == 0)
|
||||||
|
printf("[FetchFS] missing base URL, skipping fetch initialization\n");
|
||||||
|
else
|
||||||
{
|
{
|
||||||
char *path = strstr(line, " ");
|
char *base_url = strdup(line);
|
||||||
backend_t fetch;
|
backend_t fetch;
|
||||||
int fd;
|
// Don't create fetch backend unless manifest actually has entries
|
||||||
if (len <= 2 || !path)
|
while (getline(&line, &len, file) != -1)
|
||||||
{
|
{
|
||||||
printf("[FetchFS] Manifest file has invalid line %s\n", line);
|
if (!fetch)
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*path = '\0';
|
|
||||||
path += 1;
|
|
||||||
path[strcspn(path, "\r\n")] = '\0';
|
|
||||||
printf("[FetchFS] Fetch %s from %s\n", path, line);
|
|
||||||
{
|
|
||||||
char *parent = strdup(path);
|
|
||||||
path_parent_dir(parent, strlen(parent));
|
|
||||||
if (!path_mkdir(parent))
|
|
||||||
{
|
{
|
||||||
printf("[FetchFS] mkdir error %d\n", errno);
|
fetch = wasmfs_create_fetch_backend(base_url, 16*1024*1024);
|
||||||
|
wasmfs_create_directory(fetch_base_dir, 0777, fetch);
|
||||||
|
}
|
||||||
|
char *realfs_path = strstr(line, " "), *url = line;
|
||||||
|
int fd;
|
||||||
|
if(len <= 2 || !realfs_path)
|
||||||
|
{
|
||||||
|
printf("[FetchFS] Manifest file has invalid line %s\n",line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*realfs_path = '\0';
|
||||||
|
realfs_path += 1;
|
||||||
|
realfs_path[strcspn(realfs_path, "\r\n")] = '\0';
|
||||||
|
printf("[FetchFS] Fetch %s from URL %s / %s, fetched path %s / %s\n", realfs_path, base_url, url, fetch_base_dir, url);
|
||||||
|
char fetchfs_path[PATH_MAX];
|
||||||
|
fill_pathname_join(fetchfs_path, fetch_base_dir, url, sizeof(fetchfs_path));
|
||||||
|
/* Make the directories for link path */
|
||||||
|
{
|
||||||
|
char *parent = strdup(realfs_path);
|
||||||
|
path_parent_dir(parent, strlen(parent));
|
||||||
|
if(!path_mkdir(parent)) {
|
||||||
|
printf("[FetchFS] mkdir error %s %d\n", realfs_path, errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
free(parent);
|
||||||
|
}
|
||||||
|
/* Make the directories for URL path */
|
||||||
|
{
|
||||||
|
char *parent = strdup(fetchfs_path);
|
||||||
|
path_parent_dir(parent, strlen(parent));
|
||||||
|
if(!path_mkdir(parent)) {
|
||||||
|
printf("[FetchFS] mkdir error %s %d\n", fetchfs_path, errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
free(parent);
|
||||||
|
}
|
||||||
|
fd = open(fetchfs_path, O_CREAT);
|
||||||
|
if(!fd) {
|
||||||
|
printf("[FetchFS] couldn't create fetch file %s\n", fetchfs_path);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
free(parent);
|
close(fd);
|
||||||
|
if(symlink(fetchfs_path, realfs_path) != 0) {
|
||||||
|
printf("[FetchFS] couldn't create link %s to fetch file %s (errno %d)\n", realfs_path, fetchfs_path, errno);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
len = max_line_len;
|
||||||
}
|
}
|
||||||
fetch = wasmfs_create_fetch_backend(line, 16*1024*1024);
|
free(base_url);
|
||||||
if (!fetch)
|
|
||||||
{
|
|
||||||
printf("[FetchFS] couldn't create fetch backend\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
fd = wasmfs_create_file(path, 0777, fetch);
|
|
||||||
if (!fd)
|
|
||||||
{
|
|
||||||
printf("[FetchFS] couldn't create fetch file\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
len = max_line_len;
|
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
free(line);
|
free(line);
|
||||||
|
|
Loading…
Reference in New Issue