/* Copyright (C) 2010 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* * Unix implementation of wchar_t versions of POSIX filesystem functions */ #include "precompiled.h" #include "lib/sysdep/filesystem.h" #include "lib/path.h" #include struct WDIR { DIR* d; wchar_t name[PATH_MAX]; wdirent ent; }; #if OS_ANDROID // The Crystax NDK seems to do weird things with opendir etc. // To avoid that, load the symbols directly from the real libc // and use them instead. #include static void* libc; static DIR* (*libc_opendir)(const char*); static dirent* (*libc_readdir)(DIR*); static int (*libc_closedir)(DIR*); void init_libc() { if (libc) return; libc = dlopen("/system/lib/libc.so", RTLD_LAZY); ENSURE(libc); libc_opendir = (DIR*(*)(const char*))dlsym(libc, "opendir"); libc_readdir = (dirent*(*)(DIR*))dlsym(libc, "readdir"); libc_closedir = (int(*)(DIR*))dlsym(libc, "closedir"); ENSURE(libc_opendir && libc_readdir && libc_closedir); } #define opendir libc_opendir #define readdir libc_readdir #define closedir libc_closedir #else void init_libc() { } #endif WDIR* wopendir(const OsPath& path) { init_libc(); DIR* d = opendir(OsString(path).c_str()); if(!d) return 0; WDIR* wd = new WDIR; wd->d = d; wd->name[0] = '\0'; wd->ent.d_name = wd->name; return wd; } struct wdirent* wreaddir(WDIR* wd) { dirent* ent = readdir(wd->d); if(!ent) return 0; wcscpy_s(wd->name, ARRAY_SIZE(wd->name), OsPath(ent->d_name).string().c_str()); return &wd->ent; } int wclosedir(WDIR* wd) { int ret = closedir(wd->d); delete wd; return ret; } int wopen(const OsPath& pathname, int oflag) { ENSURE(!(oflag & O_CREAT)); return open(OsString(pathname).c_str(), oflag); } int wopen(const OsPath& pathname, int oflag, mode_t mode) { return open(OsString(pathname).c_str(), oflag, mode); } int wclose(int fd) { return close(fd); } int wtruncate(const OsPath& pathname, off_t length) { return truncate(OsString(pathname).c_str(), length); } int wunlink(const OsPath& pathname) { return unlink(OsString(pathname).c_str()); } int wrmdir(const OsPath& path) { return rmdir(OsString(path).c_str()); } int wrename(const OsPath& pathnameOld, const OsPath& pathnameNew) { return rename(OsString(pathnameOld).c_str(), OsString(pathnameNew).c_str()); } OsPath wrealpath(const OsPath& pathname) { char resolvedBuf[PATH_MAX]; const char* resolved = realpath(OsString(pathname).c_str(), resolvedBuf); if(!resolved) return OsPath(); return resolved; } int wstat(const OsPath& pathname, struct stat* buf) { return stat(OsString(pathname).c_str(), buf); } int wmkdir(const OsPath& path, mode_t mode) { return mkdir(OsString(path).c_str(), mode); }