/** sys_create_dir : string -> mode:int -> void <doc>Create a directory with the specified rights</doc> **/ static value sys_create_dir( value path, value mode ) { #if defined(EPPC) || defined(KORE_CONSOLE) return alloc_bool(true); #else val_check(path,string); val_check(mode,int); #ifdef NEKO_WINDOWS const wchar_t* _path = val_wstring(path); gc_enter_blocking(); if( _wmkdir(_path) != 0 ) { gc_exit_blocking(); return alloc_null(); } #else const char* _path = val_string(path); gc_enter_blocking(); if( mkdir(val_string(path),val_int(mode)) != 0 ) { gc_exit_blocking(); return alloc_null(); } #endif gc_exit_blocking(); return alloc_bool(true); #endif }
/** sys_file_type : string -> string <doc> Return the type of the file. The current values are possible : <ul> <li>[file]</li> <li>[dir]</li> <li>[symlink]</li> <li>[sock]</li> <li>[char]</li> <li>[block]</li> <li>[fifo]</li> </ul> </doc> **/ static value sys_file_type( value path ) { #if defined(EPPC) || defined(KORE_CONSOLE) return alloc_null(); #else val_check(path,string); #ifdef NEKO_WINDOWS const wchar_t* _path = val_wstring(path); gc_enter_blocking(); WIN32_FILE_ATTRIBUTE_DATA data; if( !GetFileAttributesExW(_path,GetFileExInfoStandard,&data) ) { gc_exit_blocking(); return alloc_null(); } gc_exit_blocking(); if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { return alloc_string("dir"); } else { return alloc_string("file"); } #else struct stat s; gc_enter_blocking(); if( stat(val_string(path),&s) != 0 ) { gc_exit_blocking(); return alloc_null(); } gc_exit_blocking(); if( s.st_mode & S_IFREG ) return alloc_string("file"); if( s.st_mode & S_IFDIR ) return alloc_string("dir"); if( s.st_mode & S_IFCHR ) return alloc_string("char"); #ifndef NEKO_WINDOWS if( s.st_mode & S_IFLNK ) return alloc_string("symlink"); if( s.st_mode & S_IFBLK ) return alloc_string("block"); if( s.st_mode & S_IFIFO ) return alloc_string("fifo"); if( s.st_mode & S_IFSOCK ) return alloc_string("sock"); #endif #endif return alloc_null(); #endif }
/** set_cwd : string -> void <doc>Set current working directory</doc> **/ static value set_cwd( value d ) { #if !defined(HX_WINRT) && !defined(EPPC) && !defined(KORE_CONSOLE) val_check(d,string); #ifdef NEKO_WINDOWS if( SetCurrentDirectoryW(val_wstring(d)) ) return alloc_null(); #else if( chdir(val_string(d)) ) return alloc_null(); #endif #endif return alloc_bool(true); }
/** sys_rename : from:string -> to:string -> void <doc>Rename the file or directory. Exception on error.</doc> **/ static value sys_rename( value path, value newname ) { val_check(path,string); val_check(newname,string); #if defined(NEKO_WINDOWS) && !defined(KORE_CONSOLE) const wchar_t* _path = val_wstring(path); const wchar_t* _newname = val_wstring(newname); gc_enter_blocking(); if( MoveFileExW(_path,_newname,MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH) != 0 ) { gc_exit_blocking(); return alloc_null(); } #elif (!defined(KORE_CONSOLE)) gc_enter_blocking(); if( rename(val_string(path),val_string(newname)) != 0 ) { gc_exit_blocking(); return alloc_null(); } #endif gc_exit_blocking(); return alloc_bool(true); }
/** file_open : f:string -> r:string -> 'file <doc> Call the C function [fopen] with the file path and access rights. Return the opened file or throw an exception if the file couldn't be open. </doc> **/ static value file_open( value name, value r ) { val_check(name,string); val_check(r,string); fio *f = new fio(val_filename(name)); #ifdef NEKO_WINDOWS const wchar_t *fname = val_wstring(name); const wchar_t *mode = val_wstring(r); gc_enter_blocking(); f->io = _wfopen(fname,mode); #else const char *fname = val_string(name); const char *mode = val_string(r); gc_enter_blocking(); f->io = fopen(fname,mode); #endif if( f->io == NULL ) { file_error("file_open",f,true); } gc_exit_blocking(); value result = alloc_abstract(k_file,f); val_gc(result,free_file); return result; }
/** sys_remove_dir : string -> void <doc>Remove a directory. Exception on error</doc> **/ static value sys_remove_dir( value path ) { #if defined(EPPC) || defined(KORE_CONSOLE) return alloc_bool(true); #else val_check(path,string); #ifdef NEKO_WINDOWS const wchar_t* _path = val_wstring(path); gc_enter_blocking(); bool ok = _wrmdir(_path) != 0; #else const char* _path = val_string(path); gc_enter_blocking(); bool ok = rmdir(_path) != 0; #endif gc_exit_blocking(); return alloc_bool(ok); #endif }
/** sys_exists : string -> bool <doc>Returns true if the file or directory exists.</doc> **/ static value sys_exists( value path ) { #if defined(EPPC) || defined(KORE_CONSOLE) return alloc_bool(true); #else val_check(path,string); #ifdef NEKO_WINDOWS const wchar_t* _path = val_wstring(path); gc_enter_blocking(); bool result = GetFileAttributesW(_path) != INVALID_FILE_ATTRIBUTES; #else struct stat st; gc_enter_blocking(); bool result = stat(val_string(path),&st) == 0; #endif gc_exit_blocking(); return alloc_bool(result); #endif }
/** file_full_path : string -> string <doc>Return an absolute path from a relative one. The file or directory must exists</doc> **/ static value file_full_path( value path ) { #if defined(HX_WINRT) || defined(KORE_CONSOLE) return path; #elif defined(NEKO_WINDOWS) wchar_t buf[MAX_PATH+1]; val_check(path,string); if( GetFullPathNameW(val_wstring(path),MAX_PATH+1,buf,NULL) == 0 ) return alloc_null(); return alloc_wstring(buf); #elif defined(EPPC) return path; #else char buf[PATH_MAX]; val_check(path,string); if( realpath(val_string(path),buf) == NULL ) return alloc_null(); return alloc_string(buf); #endif }
/** file_delete : string -> void <doc>Delete the file. Exception on error.</doc> **/ static value file_delete( value path ) { #if defined(EPPC) || defined(KORE_CONSOLE) return alloc_bool(true); #else val_check(path,string); #ifdef NEKO_WINDOWS const wchar_t* _path = val_wstring(path); gc_enter_blocking(); if( DeleteFileW(_path) != 0 ) #else gc_enter_blocking(); if( unlink(val_string(path)) != 0 ) #endif { gc_exit_blocking(); return alloc_null(); } gc_exit_blocking(); return alloc_bool(true); #endif }
/** file_contents : f:string -> string <doc>Read the content of the file [f] and return it.</doc> **/ static value file_contents( value name ) { buffer s=0; int len; int p; val_check(name,string); fio f(val_filename(name)); #ifdef NEKO_WINDOWS const wchar_t *fname = val_wstring(name); gc_enter_blocking(); f.io = _wfopen(fname,L"rb"); #else const char *fname = val_string(name); gc_enter_blocking(); f.io = fopen(fname,"rb"); #endif if( f.io == NULL ) file_error("file_contents",&f); fseek(f.io,0,SEEK_END); len = ftell(f.io); fseek(f.io,0,SEEK_SET); gc_exit_blocking(); s = alloc_buffer_len(len); p = 0; gc_enter_blocking(); while( len > 0 ) { int d; POSIX_LABEL(file_contents); d = (int)fread((char*)buffer_data(s)+p,1,len,f.io); if( d <= 0 ) { HANDLE_FINTR(f.io,file_contents); fclose(f.io); file_error("file_contents",&f); } p += d; len -= d; } fclose(f.io); gc_exit_blocking(); return buffer_val(s); }
/** sys_command : string -> int <doc>Run the shell command and return exit code</doc> **/ static value sys_command( value cmd ) { #if defined(HX_WINRT) || defined(EMSCRIPTEN) || defined(EPPC) || defined(IPHONE) || defined(APPLETV) || defined(HX_APPLEWATCH) || defined(KORE_CONSOLE) return alloc_int( -1 ); #else val_check(cmd,string); if( val_strlen(cmd) == 0 ) return alloc_int(-1); #ifdef NEKO_WINDOWS const wchar_t* _cmd = val_wstring(cmd); gc_enter_blocking(); int result = _wsystem(_cmd); #else gc_enter_blocking(); int result = system(val_string(cmd)); #endif gc_exit_blocking(); #if !defined(NEKO_WINDOWS) && !defined(ANDROID) result = WEXITSTATUS(result) | (WTERMSIG(result) << 8); #endif return alloc_int( result ); #endif }
/** sys_read_dir : string -> string list <doc>Return the content of a directory</doc> **/ static value sys_read_dir( value p) { val_check(p,string); value result = alloc_array(0); #ifdef HX_WINRT auto folder = (Windows::Storage::StorageFolder::GetFolderFromPathAsync( ref new Platform::String(val_wstring(p)) ))->GetResults(); auto results = folder->GetFilesAsync(Windows::Storage::Search::CommonFileQuery::DefaultQuery)->GetResults(); for(int i=0;i<results->Size;i++) val_array_push(result,alloc_wstring(results->GetAt(i)->Path->Data())); #elif defined(NEKO_WINDOWS) const wchar_t *path = val_wstring(p); size_t len = wcslen(path); if (len>MAX_PATH) return alloc_null(); WIN32_FIND_DATAW d; HANDLE handle; buffer b; wchar_t searchPath[ MAX_PATH + 4 ]; memcpy(searchPath,path, len*sizeof(wchar_t)); if( len && path[len-1] != '/' && path[len-1] != '\\' ) searchPath[len++] = '/'; searchPath[len++] = '*'; searchPath[len++] = '.'; searchPath[len++] = '*'; searchPath[len] = '\0'; gc_enter_blocking(); handle = FindFirstFileW(searchPath,&d); if( handle == INVALID_HANDLE_VALUE ) { gc_exit_blocking(); return alloc_null(); } while( true ) { // skip magic dirs if( d.cFileName[0] != '.' || (d.cFileName[1] != 0 && (d.cFileName[1] != '.' || d.cFileName[2] != 0)) ) { gc_exit_blocking(); val_array_push(result,alloc_wstring(d.cFileName)); gc_enter_blocking(); } if( !FindNextFileW(handle,&d) ) break; } FindClose(handle); gc_exit_blocking(); #elif !defined(EPPC) DIR *d; struct dirent *e; const char *name = val_string(p); gc_enter_blocking(); d = opendir(name); if( d == NULL ) { gc_exit_blocking(); val_throw(alloc_string("Invalid directory")); } while( true ) { e = readdir(d); if( e == NULL ) break; // skip magic dirs if( e->d_name[0] == '.' && (e->d_name[1] == 0 || (e->d_name[1] == '.' && e->d_name[2] == 0)) ) continue; gc_exit_blocking(); val_array_push(result, alloc_string(e->d_name) ); gc_enter_blocking(); } closedir(d); #endif gc_exit_blocking(); return result; }
/** sys_stat : string -> { gid => int, uid => int, atime => 'int32, mtime => 'int32, ctime => 'int32, dev => int, ino => int, nlink => int, rdev => int, mode => int, size => int } <doc>Run the [stat] command on the given file or directory.</doc> **/ static value sys_stat( value path ) { #if defined(EPPC) || defined(KORE_CONSOLE) return alloc_null(); #else value o; val_check(path,string); #if defined(NEKO_WINDOWS) && !defined(KORE_WINDOWSAPP) && !defined(KORE_XBOX_ONE) const wchar_t* _path = val_wstring(path); gc_enter_blocking(); WIN32_FILE_ATTRIBUTE_DATA data; if( !GetFileAttributesExW(_path,GetFileExInfoStandard,&data) ) { gc_exit_blocking(); return alloc_null(); } gc_exit_blocking(); wchar_t fullPath[MAX_PATH+1]; GetFullPathNameW(_path,MAX_PATH+1,fullPath,NULL); int dev = PathGetDriveNumberW(fullPath); #define EPOCH_DIFF (134774*24*60*60.0) ULARGE_INTEGER ui; o = alloc_empty_object( ); alloc_field(o,val_id("gid"),alloc_int(0)); alloc_field(o,val_id("uid"),alloc_int(0)); ui.LowPart = data.ftLastAccessTime.dwLowDateTime; ui.HighPart = data.ftLastAccessTime.dwHighDateTime; alloc_field(o,val_id("atime"),alloc_int32((int)(((double)ui.QuadPart) / 10000000.0 - EPOCH_DIFF))); ui.LowPart = data.ftLastWriteTime.dwLowDateTime; ui.HighPart = data.ftLastWriteTime.dwHighDateTime; alloc_field(o,val_id("mtime"),alloc_int32((int)(((double)ui.QuadPart) / 10000000.0 - EPOCH_DIFF))); ui.LowPart = data.ftCreationTime.dwLowDateTime; ui.HighPart = data.ftCreationTime.dwHighDateTime; alloc_field(o,val_id("ctime"),alloc_int32((int)(((double)ui.QuadPart) / 10000000.0 - EPOCH_DIFF))); alloc_field(o,val_id("dev"),alloc_int(dev)); alloc_field(o,val_id("ino"),alloc_int(0)); int mode = 0; if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) mode |= _S_IFDIR; if ((data.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) == 0) mode |= _S_IFREG; mode |= _S_IREAD; if ((data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0) mode |= _S_IWRITE; if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) mode |= _S_IEXEC; alloc_field(o,val_id("mode"),alloc_int(mode)); alloc_field(o,val_id("nlink"),alloc_int(1)); alloc_field(o,val_id("rdev"),alloc_int(dev)); alloc_field(o,val_id("size"),alloc_int32(data.nFileSizeLow)); #else gc_enter_blocking(); struct stat s; if( stat(val_string(path),&s) != 0 ) { gc_exit_blocking(); return alloc_null(); } gc_exit_blocking(); o = alloc_empty_object( ); STATF(gid); STATF(uid); STATF32(atime); STATF32(mtime); STATF32(ctime); STATF(dev); STATF(ino); STATF(mode); STATF(nlink); STATF(rdev); STATF(size); #endif return o; #endif }