filesystem.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #include "filesystem.h"
  2. #if _WIN32
  3. #include <windows.h>
  4. #include "../../../libc/native/libc.h"
  5. #elif __APPLE__
  6. #include <mach-o/dyld.h>
  7. #include <sys/syslimits.h>
  8. #include <limits.h>
  9. #include <dirent.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <unistd.h>
  13. #include <copyfile.h>
  14. #elif __linux
  15. #include <limits.h>
  16. #include <dirent.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <unistd.h>
  20. #else
  21. #include <limits.h>
  22. #include <dirent.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <unistd.h>
  26. #endif
  27. #if BB_ANDROID
  28. #include <sdl2/SDL/src/core/android/SDL_android.h>
  29. #endif
  30. namespace bbFileSystem{
  31. bbString _appDir;
  32. bbString _appPath;
  33. bbArray<bbString> _appArgs;
  34. struct GCRoot : public bbGCRoot{
  35. void gcMark(){
  36. bbGCMark( _appArgs );
  37. }
  38. };
  39. GCRoot root;
  40. void init(){
  41. static bool done;
  42. if( done ) return;
  43. done=true;
  44. _appArgs=bbArray<bbString>( bb_argc );
  45. for( int i=0;i<bb_argc;++i ) _appArgs[i]=bbString( bb_argv[i] );
  46. #if _WIN32
  47. WCHAR buf[MAX_PATH];
  48. GetModuleFileNameW( GetModuleHandleW(0),buf,MAX_PATH );
  49. buf[MAX_PATH-1]=0;
  50. for( WCHAR *p=buf;*p;++p ) if( *p=='\\' ) *p='/';
  51. _appPath=bbString( buf );
  52. #elif __APPLE__
  53. char buf[PATH_MAX];
  54. uint32_t size=sizeof( buf );
  55. _NSGetExecutablePath( buf,&size );
  56. buf[PATH_MAX-1]=0;
  57. _appPath=bbString( buf );
  58. #elif __linux
  59. pid_t pid=getpid();
  60. char lnk[PATH_MAX];
  61. char buf[PATH_MAX];
  62. sprintf( lnk,"/proc/%i/exe",pid );
  63. int i=readlink( lnk,buf,PATH_MAX );
  64. if( i>0 && i<PATH_MAX ){
  65. buf[i]=0;
  66. _appPath=bbString( buf );
  67. }
  68. #else
  69. _appPath="/";
  70. #endif
  71. int e=_appPath.findLast( "/" );
  72. if( e!=-1 ){
  73. _appDir=_appPath.slice( 0,e+1 );
  74. }else{
  75. _appDir=_appPath;
  76. }
  77. }
  78. bbString appDir(){
  79. init();
  80. return _appDir;
  81. }
  82. bbString appPath(){
  83. init();
  84. return _appPath;
  85. }
  86. bbArray<bbString> appArgs(){
  87. init();
  88. return _appArgs;
  89. }
  90. bbBool copyFile( bbString srcPath,bbString dstPath ){
  91. #if _WIN32
  92. // return CopyFileW( bbWString( srcPath ),bbWString( dstPath ),FALSE );
  93. return CopyFileW( widen_utf8( bbCString( srcPath ) ),widen_utf8( bbCString( dstPath ) ),FALSE );
  94. #elif __APPLE__
  95. int ret=copyfile( bbCString( srcPath ),bbCString( dstPath ),0,COPYFILE_ALL );
  96. if( ret>=0 ) return true;
  97. // printf( "copyfile failed, ret=%i\n",ret );
  98. // printf( "src=%s\n",srcPath.c_str() );
  99. // printf( "dst=%s\n",dstPath.c_str() );
  100. return false;
  101. #else
  102. //TODO: use sendfile() here?
  103. //
  104. int err=-1;
  105. if( FILE *srcp=fopen( bbCString( srcPath ),"rb" ) ){
  106. err=-2;
  107. if( FILE *dstp=fopen( bbCString( dstPath ),"wb" ) ){
  108. err=0;
  109. char buf[1024];
  110. while( int n=fread( buf,1,1024,srcp ) ){
  111. if( fwrite( buf,1,n,dstp )!=n ){
  112. err=-3;
  113. break;
  114. }
  115. }
  116. fclose( dstp );
  117. }else{
  118. // printf( "FOPEN 'wb' for CopyFile(%s,%s) failed\n",C_STR(srcpath),C_STR(dstpath) );
  119. fflush( stdout );
  120. }
  121. fclose( srcp );
  122. }else{
  123. // printf( "FOPEN 'rb' for CopyFile(%s,%s) failed\n",C_STR(srcpath),C_STR(dstpath) );
  124. fflush( stdout );
  125. }
  126. return err==0;
  127. #endif
  128. }
  129. #if BB_ANDROID
  130. int android_read( void *cookie,char *buf,int size ){
  131. return AAsset_read( (AAsset*)cookie,buf,size );
  132. }
  133. int android_write( void *cookie,const char* buf,int size ){
  134. return EACCES; // can't provide write access to the apk
  135. }
  136. fpos_t android_seek( void *cookie,fpos_t offset,int whence ){
  137. return AAsset_seek( (AAsset*)cookie,offset,whence );
  138. }
  139. int android_close(void* cookie) {
  140. AAsset_close( (AAsset*)cookie );
  141. return 0;
  142. }
  143. FILE *fopenAsset( void *asset ){
  144. return funopen( asset,android_read,android_write,android_seek,android_close );
  145. }
  146. #endif
  147. /*
  148. FILE *fopen( const char *path,const char *mode ){
  149. #if BB_ANDROID
  150. if( !strncmp( path,"asset::",7 ) ){
  151. AAssetManager *assetManager=Android_JNI_GetAssetManager();
  152. if( !assetManager ) return 0;
  153. AAsset* asset=AAssetManager_open( assetManager,path+7,0 );
  154. if( !asset ) return 0;
  155. return fopenAsset( asset );
  156. }
  157. #endif
  158. return ::fopen( path,mode );
  159. }
  160. */
  161. }