#include "tier0/platform.h" #include "tier0/lib.h" #include "stdarg.h" #include "unistd.h" #include "sys/stat.h" #include "execinfo.h" #include "dirent.h" #include "dlfcn.h" #include "time.h" PLATFORM_INTERFACE void Plat_FatalErrorFunc(const char* szFormat, ...) { va_list list; va_start(list, szFormat); V_vprintf(szFormat, list); va_end(list); fflush(stdout); _exit(1); } PLATFORM_INTERFACE void Plat_ListDirRecursive(const char* szPath, ListDirCallbackFn file, ListDirCallbackFn dir) { struct dirent *entry; DIR *dp = opendir(szPath); if (!dp) { return; } while ((entry = readdir(dp)) != NULL) { char full_path[1024]; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; snprintf(full_path, sizeof(full_path), "%s/%s", szPath, entry->d_name); struct stat statbuf; if (stat(full_path, &statbuf) == -1) { continue; } if (S_ISDIR(statbuf.st_mode)) { if (dir) dir(full_path); Plat_ListDirRecursive(full_path, file, dir); } else { if (file) file(full_path); } } closedir(dp); } PLATFORM_INTERFACE void Plat_ListDir(const char* szPath, ListDirCallbackFn file, ListDirCallbackFn dir) { } PLATFORM_INTERFACE char *Plat_GetExtension( const char *szPath ) { char *last = (char*)szPath + V_strlen(szPath) - 1; while (last != szPath) { if (*last=='.') { break; }; if (*last=='/') { return 0; } last--; } return last+1; } PLATFORM_INTERFACE void Plat_Backtrace( void ) { void *buffer[64]; int nptrs = backtrace(buffer, 64); char **symbols = backtrace_symbols(buffer, nptrs); if (symbols == NULL) { V_printf("Backtrace failed\n"); exit(EXIT_FAILURE); } for (int i = 0; i < nptrs; i++) { V_printf(" [%d] %s\n", i, symbols[i]); } free(symbols); }; PLATFORM_INTERFACE void *Plat_LoadLibrary( const char *psz ) { void *lib = dlopen(psz, RTLD_GLOBAL | RTLD_NOW); if (!lib) V_printf("Failed to open %s\n\t%s\n", psz, dlerror()); return lib; } PLATFORM_INTERFACE void *Plat_GetProc( void *lib, const char *psz ) { return dlsym(lib, psz); } PLATFORM_INTERFACE void Plat_UnloadLibrary( void *lib ) { dlclose(lib); }; PLATFORM_INTERFACE double Plat_GetTime( void ) { struct timespec tp; clock_gettime(CLOCK_MONOTONIC, &tp); static time_t s_starttime = tp.tv_sec; return (tp.tv_sec-s_starttime)+tp.tv_nsec/1e9; }