Line data Source code
1 : /* Copyright (C) 2010 Wildfire Games.
2 : *
3 : * Permission is hereby granted, free of charge, to any person obtaining
4 : * a copy of this software and associated documentation files (the
5 : * "Software"), to deal in the Software without restriction, including
6 : * without limitation the rights to use, copy, modify, merge, publish,
7 : * distribute, sublicense, and/or sell copies of the Software, and to
8 : * permit persons to whom the Software is furnished to do so, subject to
9 : * the following conditions:
10 : *
11 : * The above copyright notice and this permission notice shall be included
12 : * in all copies or substantial portions of the Software.
13 : *
14 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 : * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 : * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 : * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 : * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 : * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 : */
22 :
23 : /*
24 : * Unix implementation of wchar_t versions of POSIX filesystem functions
25 : */
26 :
27 : #include "precompiled.h"
28 : #include "lib/sysdep/filesystem.h"
29 :
30 : #include "lib/path.h"
31 :
32 : #include <cstdio>
33 :
34 : struct WDIR
35 : {
36 : DIR* d;
37 : wchar_t name[PATH_MAX];
38 : wdirent ent;
39 : };
40 :
41 : #if OS_ANDROID
42 :
43 : // The Crystax NDK seems to do weird things with opendir etc.
44 : // To avoid that, load the symbols directly from the real libc
45 : // and use them instead.
46 :
47 : #include <dlfcn.h>
48 :
49 : static void* libc;
50 : static DIR* (*libc_opendir)(const char*);
51 : static dirent* (*libc_readdir)(DIR*);
52 : static int (*libc_closedir)(DIR*);
53 :
54 : void init_libc()
55 : {
56 : if (libc)
57 : return;
58 : libc = dlopen("/system/lib/libc.so", RTLD_LAZY);
59 : ENSURE(libc);
60 : libc_opendir = (DIR*(*)(const char*))dlsym(libc, "opendir");
61 : libc_readdir = (dirent*(*)(DIR*))dlsym(libc, "readdir");
62 : libc_closedir = (int(*)(DIR*))dlsym(libc, "closedir");
63 : ENSURE(libc_opendir && libc_readdir && libc_closedir);
64 : }
65 :
66 : #define opendir libc_opendir
67 : #define readdir libc_readdir
68 : #define closedir libc_closedir
69 :
70 : #else
71 :
72 995 : void init_libc() { }
73 :
74 : #endif
75 :
76 995 : WDIR* wopendir(const OsPath& path)
77 : {
78 995 : init_libc();
79 995 : DIR* d = opendir(OsString(path).c_str());
80 995 : if(!d)
81 129 : return 0;
82 866 : WDIR* wd = new WDIR;
83 866 : wd->d = d;
84 866 : wd->name[0] = '\0';
85 866 : wd->ent.d_name = wd->name;
86 866 : return wd;
87 : }
88 :
89 5427 : struct wdirent* wreaddir(WDIR* wd)
90 : {
91 5427 : dirent* ent = readdir(wd->d);
92 5427 : if(!ent)
93 767 : return 0;
94 4660 : wcscpy_s(wd->name, ARRAY_SIZE(wd->name), OsPath(ent->d_name).string().c_str());
95 4660 : return &wd->ent;
96 : }
97 :
98 866 : int wclosedir(WDIR* wd)
99 : {
100 866 : int ret = closedir(wd->d);
101 866 : delete wd;
102 866 : return ret;
103 : }
104 :
105 :
106 0 : int wopen(const OsPath& pathname, int oflag)
107 : {
108 0 : ENSURE(!(oflag & O_CREAT));
109 0 : return open(OsString(pathname).c_str(), oflag);
110 : }
111 :
112 2934 : int wopen(const OsPath& pathname, int oflag, mode_t mode)
113 : {
114 2934 : return open(OsString(pathname).c_str(), oflag, mode);
115 : }
116 :
117 2934 : int wclose(int fd)
118 : {
119 2934 : return close(fd);
120 : }
121 :
122 :
123 97 : int wtruncate(const OsPath& pathname, off_t length)
124 : {
125 97 : return truncate(OsString(pathname).c_str(), length);
126 : }
127 :
128 94 : int wunlink(const OsPath& pathname)
129 : {
130 94 : return unlink(OsString(pathname).c_str());
131 : }
132 :
133 239 : int wrmdir(const OsPath& path)
134 : {
135 239 : return rmdir(OsString(path).c_str());
136 : }
137 :
138 0 : int wrename(const OsPath& pathnameOld, const OsPath& pathnameNew)
139 : {
140 0 : return rename(OsString(pathnameOld).c_str(), OsString(pathnameNew).c_str());
141 : }
142 :
143 0 : OsPath wrealpath(const OsPath& pathname)
144 : {
145 : char resolvedBuf[PATH_MAX];
146 0 : const char* resolved = realpath(OsString(pathname).c_str(), resolvedBuf);
147 0 : if(!resolved)
148 0 : return OsPath();
149 0 : return resolved;
150 : }
151 :
152 4970 : int wstat(const OsPath& pathname, struct stat* buf)
153 : {
154 4970 : return stat(OsString(pathname).c_str(), buf);
155 : }
156 :
157 239 : int wmkdir(const OsPath& path, mode_t mode)
158 : {
159 239 : return mkdir(OsString(path).c_str(), mode);
160 3 : }
|