11#include <dirent.h>
22#include <errno.h>
3+ #include <m-dict.h>
34#include <psp2/kernel/error.h>
45#include <psp2common/types.h>
56#include <stdarg.h>
1314
1415#include "log.h"
1516#include "module.h"
16- #include "protected_bitset.h"
1717#include "util.h"
1818
1919#include "modules/SceKernelThreadMgr.h"
2020#include "modules/SceLibKernel.h"
2121#include "modules/SceSysmem.h"
2222
23- #define MAX_OPENED_FILES 32
24- #define MAX_OPENED_DIRS 32
25-
2623typedef struct {
2724 uint32_t index ;
2825 SceUID uid ;
@@ -40,15 +37,35 @@ typedef struct {
4037static UEvent g_process_exit_event ;
4138static atomic_int g_process_exit_res ;
4239
43- DECL_PROTECTED_BITSET (VitaOpenedFile , vita_opened_files , MAX_OPENED_FILES )
44- DECL_PROTECTED_BITSET_ALLOC (opened_file_alloc , vita_opened_files , VitaOpenedFile )
45- DECL_PROTECTED_BITSET_RELEASE (opened_file_release , vita_opened_files , VitaOpenedFile )
46- DECL_PROTECTED_BITSET_GET_FOR_UID (get_opened_file_for_fd , vita_opened_files , VitaOpenedFile )
40+ DICT_DEF2 (vita_opened_files_dict , SceUID , M_DEFAULT_OPLIST , VitaOpenedFile * , M_POD_OPLIST )
41+ static vita_opened_files_dict_t g_vita_opened_files ;
42+ static RwLock g_vita_opened_files_lock ;
43+
44+ DICT_DEF2 (vita_opened_dirs_dict , SceUID , M_DEFAULT_OPLIST , VitaOpenedDir * , M_POD_OPLIST )
45+ static vita_opened_dirs_dict_t g_vita_opened_dirs ;
46+ static RwLock g_vita_opened_dirs_lock ;
47+
48+ static VitaOpenedFile * get_opened_file_for_fd (SceUID fd )
49+ {
50+ VitaOpenedFile * vfile ;
4751
48- DECL_PROTECTED_BITSET (VitaOpenedDir , vita_opened_dirs , MAX_OPENED_DIRS )
49- DECL_PROTECTED_BITSET_ALLOC (opened_dir_alloc , vita_opened_dirs , VitaOpenedDir )
50- DECL_PROTECTED_BITSET_RELEASE (opened_dir_release , vita_opened_dirs , VitaOpenedDir )
51- DECL_PROTECTED_BITSET_GET_FOR_UID (get_opened_dir_for_fd , vita_opened_dirs , VitaOpenedDir )
52+ rwlockReadLock (& g_vita_opened_files_lock );
53+ vfile = * vita_opened_files_dict_get (g_vita_opened_files , fd );
54+ rwlockReadUnlock (& g_vita_opened_files_lock );
55+
56+ return vfile ;
57+ }
58+
59+ static VitaOpenedDir * get_opened_dir_for_fd (SceUID fd )
60+ {
61+ VitaOpenedDir * vdir ;
62+
63+ rwlockReadLock (& g_vita_opened_dirs_lock );
64+ vdir = * vita_opened_dirs_dict_get (g_vita_opened_dirs , fd );
65+ rwlockReadUnlock (& g_vita_opened_dirs_lock );
66+
67+ return vdir ;
68+ }
5269
5370EXPORT (SceLibKernel , 0xB295EB61 , void * , sceKernelGetTLSAddr , int key )
5471{
@@ -149,32 +166,40 @@ EXPORT(SceLibKernel, 0x6C60AC61, SceUID, sceIoOpen, const char *file, int flags,
149166 if (!fp )
150167 return SCE_ERROR_ERRNO_ENODEV ;
151168
152- vfile = opened_file_alloc ( );
169+ vfile = malloc ( sizeof ( * vfile ) );
153170 if (!vfile ) {
154171 fclose (fp );
155172 return SCE_ERROR_ERRNO_EMFILE ;
156173 }
157174
175+ memset (vfile , 0 , sizeof (* vfile ));
158176 vfile -> uid = SceSysmem_get_next_uid ();
159177 vfile -> fp = fp ;
160178 vfile -> file = strdup (file );
161179
180+ rwlockWriteLock (& g_vita_opened_files_lock );
181+ vita_opened_files_dict_set_at (g_vita_opened_files , vfile -> uid , vfile );
182+ rwlockWriteUnlock (& g_vita_opened_files_lock );
183+
162184 return vfile -> uid ;
163185}
164186
165187EXPORT (SceIofilemgr , 0xC70B8886 , int , sceIoClose , SceUID fd )
166188{
167189 VitaOpenedFile * vfile = get_opened_file_for_fd (fd );
168- FILE * fp ;
190+ int ret ;
169191
170192 if (!vfile )
171193 return SCE_ERROR_ERRNO_EBADF ;
172194
173- fp = vfile -> fp ;
195+ ret = fclose (vfile -> fp );
196+ rwlockWriteLock (& g_vita_opened_files_lock );
197+ vita_opened_files_dict_erase (g_vita_opened_files , fd );
198+ rwlockWriteUnlock (& g_vita_opened_files_lock );
174199 free (vfile -> file );
175- opened_file_release (vfile );
200+ free (vfile );
176201
177- if (fclose ( fp ) )
202+ if (ret )
178203 return SCE_ERROR_ERRNO_EBADF ;
179204
180205 return 0 ;
@@ -230,32 +255,40 @@ EXPORT(SceLibKernel, 0xA9283DD0, SceUID, sceIoDopen, const char *dirname)
230255 if (!dir )
231256 return SCE_ERROR_ERRNO_ENODEV ;
232257
233- vdir = opened_dir_alloc ( );
258+ vdir = malloc ( sizeof ( * vdir ) );
234259 if (!vdir ) {
235260 closedir (dir );
236261 return SCE_ERROR_ERRNO_EMFILE ;
237262 }
238263
264+ memset (vdir , 0 , sizeof (* vdir ));
239265 vdir -> uid = SceSysmem_get_next_uid ();
240266 vdir -> dir = dir ;
241267 vdir -> path = strdup (dirname );
242268
269+ rwlockWriteLock (& g_vita_opened_dirs_lock );
270+ vita_opened_dirs_dict_set_at (g_vita_opened_dirs , vdir -> uid , vdir );
271+ rwlockWriteUnlock (& g_vita_opened_dirs_lock );
272+
243273 return vdir -> uid ;
244274}
245275
246276EXPORT (SceIofilemgr , 0x422A221A , int , sceIoDclose , SceUID fd )
247277{
248278 VitaOpenedDir * vdir = get_opened_dir_for_fd (fd );
249- DIR * dir ;
279+ int ret ;
250280
251281 if (!vdir )
252282 return SCE_ERROR_ERRNO_EBADF ;
253283
254- dir = vdir -> dir ;
284+ ret = closedir ( vdir -> dir ) ;
255285 free (vdir -> path );
256- opened_dir_release (vdir );
286+ rwlockWriteLock (& g_vita_opened_dirs_lock );
287+ vita_opened_dirs_dict_erase (g_vita_opened_dirs , fd );
288+ rwlockWriteUnlock (& g_vita_opened_dirs_lock );
289+ free (vdir );
257290
258- if (closedir ( dir ) )
291+ if (ret )
259292 return SCE_ERROR_ERRNO_EBADF ;
260293
261294 return 0 ;
0 commit comments