]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
More NaCl support. We need to emulate listdirectory().
authorRudolf Polzer <divVerent@xonotic.org>
Wed, 23 Sep 2015 14:42:20 +0000 (10:42 -0400)
committerRudolf Polzer <divVerent@xonotic.org>
Wed, 23 Sep 2015 14:42:20 +0000 (10:42 -0400)
filematch.c
fs.c
fs.h
makefile
sys_sdl.c
zone.c

index 754d362c23e2c4d423ed4ff6712fe8e1233553cb..ae51599bf8969a4220a6279081c69e8cd92ab26d 100644 (file)
@@ -192,14 +192,24 @@ void listdirectory(stringlist_t *list, const char *basepath, const char *path)
        char fullpath[MAX_OSPATH];
        DIR *dir;
        struct dirent *ent;
-       dpsnprintf(fullpath, sizeof(fullpath), "%s%s", basepath, *path ? path : "./");
-       dir = opendir(fullpath);
-       if (!dir)
+       dpsnprintf(fullpath, sizeof(fullpath), "%s%s", basepath, path);
 #ifdef __native_client__
+       // In NaCl, only html5fs supports readdir. And attempting to readdir a
+       // directory before opening a file in it will actually mark the
+       // directory as a file for httpfs, leading to files inside becoming
+       // inaccessible. So our only solution is to read text files as a virtual
+       // directory listing. Create using "ls > .ls.txt" in any httpfs
+       // directory you want to support.
+       if (strncmp(basepath, "/.", 2))
        {
                char listpath[MAX_OSPATH];
+               qfile_t *listfile;
                dpsnprintf(listpath, sizeof(listpath), "%s.ls.txt", fullpath);
-               char *buf = (char *) FS_LoadFile(listpath, tempmempool, true, NULL);
+               listfile = FS_SysOpen(listpath, "rb", false);
+               if (!listfile)
+                       return;
+               char *buf = (char *) FS_LoadQFile(listfile, tempmempool, true, NULL);
+               FS_Close(listfile);
                if (!buf)
                        return;
                char *p = buf;
@@ -209,14 +219,18 @@ void listdirectory(stringlist_t *list, const char *basepath, const char *path)
                        if (q == NULL)
                                break;
                        *q = 0;
+                        Con_Printf("Got file: %s\n", p);
                        adddirentry(list, path, p);
                        p = q + 1;
                }
                Mem_Free(buf);
-       }
-#else
                return;
+       }
 #endif
+       dir = opendir(fullpath);
+       if (!dir)
+               return;
+       
        while ((ent = readdir(dir)))
                adddirentry(list, path, ent->d_name);
        closedir(dir);
diff --git a/fs.c b/fs.c
index e682f6fa482942776d040aa0198388905dec0cc5..550503cbf769060897fadcb53aab93a44e77238a 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -226,7 +226,7 @@ struct qfile_s
 
        const unsigned char *data;      ///< For data files.
 
-       const char *filename; ///< Kept around for QFILE_FLAG_REMOVE, unused otherwise
+       const char *filename; ///< Kept around for QFILE_FLAG_REMOVE and logging, unused otherwise
 };
 
 
@@ -339,7 +339,11 @@ const char *const fs_checkgamedir_missing = "missing";
 #define MAX_FILES_IN_PACK      65536
 
 char fs_userdir[MAX_OSPATH];
+char fs_cachedir[MAX_OSPATH];
+
 char fs_gamedir[MAX_OSPATH];
+char fs_gamecachedir[MAX_OSPATH];
+
 char fs_basedir[MAX_OSPATH];
 static pack_t *fs_selfpack = NULL;
 
@@ -1230,13 +1234,16 @@ Sets fs_gamedir, adds the directory to the head of the path,
 then loads and adds pak1.pak pak2.pak ...
 ================
 */
-static void FS_AddGameDirectory (const char *dir)
+static void FS_AddGameDirectory (const char *dir, qboolean iscache)
 {
        int i;
        stringlist_t list;
        searchpath_t *search;
 
-       strlcpy (fs_gamedir, dir, sizeof (fs_gamedir));
+       if (iscache)
+               strlcpy (fs_gamedir, dir, sizeof (fs_gamedir));
+       else
+               strlcpy (fs_gamecachedir, dir, sizeof (fs_gamedir));
 
        stringlistinit(&list);
        listdirectory(&list, "", dir);
@@ -1280,10 +1287,12 @@ static void FS_AddGameHierarchy (const char *dir)
 {
        char vabuf[1024];
        // Add the common game directory
-       FS_AddGameDirectory (va(vabuf, sizeof(vabuf), "%s%s/", fs_basedir, dir));
+       FS_AddGameDirectory (va(vabuf, sizeof(vabuf), "%s%s/", fs_basedir, dir), false);
 
+       if (*fs_cachedir)
+               FS_AddGameDirectory(va(vabuf, sizeof(vabuf), "%s%s/", fs_cachedir, dir), true);
        if (*fs_userdir)
-               FS_AddGameDirectory(va(vabuf, sizeof(vabuf), "%s%s/", fs_userdir, dir));
+               FS_AddGameDirectory(va(vabuf, sizeof(vabuf), "%s%s/", fs_userdir, dir), false);
 }
 
 
@@ -1779,14 +1788,26 @@ void FS_Init_SelfPack (void)
        }
 }
 
-static int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsize)
+static int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t userdirsize, char *cachedir, size_t cachedirsize)
 {
+       *userdir = 0;
+       *cachedir = 0;
+
 #if defined(__IPHONEOS__)
        if (userdirmode == USERDIRMODE_HOME)
        {
                // fs_basedir is "" by default, to utilize this you can simply add your gamedir to the Resources in xcode
                // fs_userdir stores configurations to the Documents folder of the app
-               strlcpy(userdir, "../Documents/", MAX_OSPATH);
+               strlcpy(userdir, "../Documents/", userdirsize);
+               return 1;
+       }
+       return -1;
+
+#elif defined(__native_client__)
+       if (userdirmode == USERDIRMODE_HOME)
+       {
+               dpsnprintf(userdir, userdirsize, "/.config/%s/", gameuserdirname);
+               dpsnprintf(cachedir, cachedirsize, "/.cache/%s/", gameuserdirname);
                return 1;
        }
        return -1;
@@ -1915,7 +1936,7 @@ static int FS_ChooseUserDir(userdirmode_t userdirmode, char *userdir, size_t use
 #endif
 
 
-#if !defined(__IPHONEOS__)
+#if !defined(__IPHONEOS__) && !defined(__native_client__)
 
 #ifdef WIN32
        // historical behavior...
@@ -1962,7 +1983,9 @@ void FS_Init (void)
 
        *fs_basedir = 0;
        *fs_userdir = 0;
+       *fs_cachedir = 0;
        *fs_gamedir = 0;
+       *fs_gamecachedir = 0;
 
        // -basedir <path>
        // Overrides the system supplied base directory (under GAMENAME)
@@ -2043,7 +2066,7 @@ void FS_Init (void)
                // gather the status of the possible userdirs
                for (dirmode = 0;dirmode < USERDIRMODE_COUNT;dirmode++)
                {
-                       userdirstatus[dirmode] = FS_ChooseUserDir((userdirmode_t)dirmode, fs_userdir, sizeof(fs_userdir));
+                       userdirstatus[dirmode] = FS_ChooseUserDir((userdirmode_t)dirmode, fs_userdir, sizeof(fs_userdir), fs_cachedir, sizeof(fs_cachedir));
                        if (userdirstatus[dirmode] == 1)
                                Con_DPrintf("userdir %i = %s (writable)\n", dirmode, fs_userdir);
                        else if (userdirstatus[dirmode] == 0)
@@ -2065,7 +2088,7 @@ void FS_Init (void)
                                if (userdirstatus[dirmode] >= 0)
                                        break;
                // and finally, we picked one...
-               FS_ChooseUserDir((userdirmode_t)dirmode, fs_userdir, sizeof(fs_userdir));
+               FS_ChooseUserDir((userdirmode_t)dirmode, fs_userdir, sizeof(fs_userdir), fs_cachedir, sizeof(fs_cachedir));
                Con_DPrintf("userdir %i is the winner\n", dirmode);
        }
 
@@ -2642,7 +2665,10 @@ qfile_t* FS_OpenRealFile (const char* filepath, const char* mode, qboolean quiet
                return NULL;
        }
 
-       dpsnprintf (real_path, sizeof (real_path), "%s/%s", fs_gamedir, filepath); // this is never a vpack
+       if (!strncmp(filepath, "dlcache/", 8))
+               dpsnprintf (real_path, sizeof (real_path), "%s/%s", fs_gamecachedir, filepath); // this is never a vpack
+       else
+               dpsnprintf (real_path, sizeof (real_path), "%s/%s", fs_gamedir, filepath); // this is never a vpack
 
        // If the file is opened in "write", "append", or "read/write" mode,
        // create directories up to the file.
@@ -3226,6 +3252,31 @@ void FS_Purge (qfile_t* file)
 }
 
 
+/*
+============
+FS_LoadQFile
+
+Loads a file content from a qfile_t.
+============
+*/
+unsigned char *FS_LoadQFile (qfile_t *file, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer)
+{
+       unsigned char *buf;
+       fs_offset_t filesize = file->real_length;
+       if(filesize < 0)
+       {
+               Con_Printf("FS_LoadQFile(\"%s\", pool, %s, filesizepointer): trying to open a non-regular file\n", file->filename, quiet ? "true" : "false");
+               return NULL;
+       }
+       buf = (unsigned char *)Mem_Alloc (pool, filesize + 1);
+       buf[filesize] = '\0';
+       FS_Read (file, buf, filesize);
+       if (filesizepointer)
+               *filesizepointer = filesize;
+       return buf;
+}
+
+
 /*
 ============
 FS_LoadFile
@@ -3238,29 +3289,14 @@ unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, f
 {
        qfile_t *file;
        unsigned char *buf = NULL;
-       fs_offset_t filesize = 0;
-
        file = FS_OpenVirtualFile(path, quiet);
-       if (file)
-       {
-               filesize = file->real_length;
-               if(filesize < 0)
-               {
-                       Con_Printf("FS_LoadFile(\"%s\", pool, %s, filesizepointer): trying to open a non-regular file\n", path, quiet ? "true" : "false");
-                       FS_Close(file);
-                       return NULL;
-               }
-
-               buf = (unsigned char *)Mem_Alloc (pool, filesize + 1);
-               buf[filesize] = '\0';
-               FS_Read (file, buf, filesize);
-               FS_Close (file);
-               if (developer_loadfile.integer)
-                       Con_Printf("loaded file \"%s\" (%u bytes)\n", path, (unsigned int)filesize);
-       }
-
-       if (filesizepointer)
-               *filesizepointer = filesize;
+       if (!file)
+               return NULL;
+       buf = FS_LoadQFile(file, pool, quiet, filesizepointer);
+       if (buf == NULL)
+               return NULL;
+       if (developer_loadfile.integer)
+               Con_Printf("loaded file \"%s\"\n", path);
        return buf;
 }
 
diff --git a/fs.h b/fs.h
index 657f6440a5a721a16bb03d868e4cdec1b1c911a2..e3dbfa1009143a57ebf0681d2ece5124b01425a8 100644 (file)
--- a/fs.h
+++ b/fs.h
@@ -110,6 +110,7 @@ fssearch_t;
 fssearch_t *FS_Search(const char *pattern, int caseinsensitive, int quiet);
 void FS_FreeSearch(fssearch_t *search);
 
+unsigned char *FS_LoadQFile (qfile_t *file, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer);
 unsigned char *FS_LoadFile (const char *path, mempool_t *pool, qboolean quiet, fs_offset_t *filesizepointer);
 qboolean FS_WriteFileInBlocks (const char *filename, const void *const *data, const fs_offset_t *len, size_t count);
 qboolean FS_WriteFile (const char *filename, const void *data, fs_offset_t len);
index 97f428b136c3cd8b9289fdcd9b1d482d9be0a3e7..9d74a8d80929d466bd39cd1860813a7d02eab110 100644 (file)
--- a/makefile
+++ b/makefile
@@ -125,9 +125,9 @@ ifeq ($(DP_MAKE_TARGET), pnacl)
 
        LDFLAGS_CL=BRLOGENSHFEGLE
        # TODO is there a better way to get this path?
-       LDFLAGS_SV=$(LDFLAGS_UNIXCOMMON) -L$(HOME)/nacl_sdk/pepper_44/lib/pnacl/Release
+       LDFLAGS_SV=$(LDFLAGS_UNIXCOMMON) -L$(HOME)/nacl_sdk/pepper_44/lib/pnacl/Release -L$(HOME)/nacl_sdk/pepper_44/ports/lib/newlib_pnacl/Release
        # TODO is there a better way to get this path?
-       LDFLAGS_SDL=$(LDFLAGS_UNIXSDL) -L$(HOME)/nacl_sdk/pepper_44/lib/pnacl/Release
+       LDFLAGS_SDL=$(LDFLAGS_UNIXCOMMON) $(LDFLAGS_UNIXSDL) -L$(HOME)/nacl_sdk/pepper_44/lib/pnacl/Release -L$(HOME)/nacl_sdk/pepper_44/ports/lib/newlib_pnacl/Release
 
        SDLCONFIG_CFLAGS=$(SDLCONFIG_UNIXCFLAGS)
        SDLCONFIG_LIBS=$(SDLCONFIG_STATICLIBS)
@@ -141,15 +141,15 @@ ifeq ($(DP_MAKE_TARGET), pnacl)
        EXE_SVNEXUIZ=$(EXE_UNIXSVNEXUIZ)
        EXE_SDLNEXUIZ=$(EXE_UNIXSDLNEXUIZ)
 
-       DP_LINK_ZLIB?=dlopen
-       DP_LINK_JPEG?=dlopen
+       DP_LINK_ZLIB?=shared
+       DP_LINK_JPEG?=shared
        DP_LINK_ODE?=dlopen
        DP_LINK_CRYPTO?=dlopen
        DP_LINK_CRYPTO_RIJNDAEL?=dlopen
 
        # TODO is there a better way to get this path?
        # TODO is net/if.h really missing?
-       CFLAGS_EXTRA=-I$(HOME)/nacl_sdk/pepper_44/include -I$(HOME)/nacl_sdk/pepper_44/include/pnacl $(SDLCONFIG_CFLAGS) -DNOSUPPORTIPV6
+       CFLAGS_EXTRA=-I$(HOME)/nacl_sdk/pepper_44/include -I$(HOME)/nacl_sdk/pepper_44/include/pnacl -I$(HOME)/nacl_sdk/pepper_44/ports/include $(SDLCONFIG_CFLAGS) -DNOSUPPORTIPV6
        CFLAGS_SSE=
        CFLAGS_SSE2=
 
index 54651b44698a8ab106c4a2e10b059299a6bc89f1..9d261de4efc0667a51aa6966f20b808f75d1046b 100644 (file)
--- a/sys_sdl.c
+++ b/sys_sdl.c
@@ -206,8 +206,8 @@ void Sys_InitConsole (void)
 static void NaCl_Init(void)
 {
        mount("", "/dev", "dev", 0, "");
-       mount("", "/.persistentfs", "html5fs", 0, "type=PERSISTENT,expected_size=8388608");
-       mount("", "/.tempfs", "html5fs", 0, "type=TEMPORARY,expected_size=1073741824");
+       mount("", "/.config", "html5fs", 0, "type=PERSISTENT,expected_size=8388608");
+       mount("", "/.cache", "html5fs", 0, "type=TEMPORARY,expected_size=1073741824");
        int fd = open("/dev/console0", O_WRONLY, 0644);
        outfd = fd;
 }
diff --git a/zone.c b/zone.c
index fe80693ce342fd08b9ac2171d8129f4212d76a2a..b7cc5b8f9f78158b7d3aa8a8f0ab638555de36d1 100644 (file)
--- a/zone.c
+++ b/zone.c
@@ -953,6 +953,7 @@ void Memory_Init_Commands (void)
                // first guess
                Cvar_SetValueQuick(&sys_memsize_virtual, (sizeof(void*) == 4) ? 2048 : 268435456);
                // then improve
+#ifndef __native_client__
                {
                        // Linux, and BSD with linprocfs mounted
                        FILE *f = fopen("/proc/meminfo", "r");
@@ -980,6 +981,7 @@ void Memory_Init_Commands (void)
                                fclose(f);
                        }
                }
+#endif
        }
 #endif
 }