/* Win32 shim for (chibi filesystem) */ #include #include #include #include #include static int mkdir_shim(const char* path, int ignored) { return mkdir(path); } #if !defined(__MINGW32__) && !defined(__MINGW64__) /* Flags for _access() API */ #define R_OK 4 #define W_OK 2 #define X_OK 1 /* Follow MinGW */ #define SHIM_WIN32_STAT_IS(m, flg) ((m & _S_IFMT) == flg) #define S_ISREG(m) SHIM_WIN32_STAT_IS(m, _S_IFREG) #define S_ISDIR(m) SHIM_WIN32_STAT_IS(m, _S_IFDIR) #define S_ISCHR(m) SHIM_WIN32_STAT_IS(m, _S_IFCHR) #define S_ISFIFO(m) SHIM_WIN32_STAT_IS(m, _S_IFIFO) #define S_ISBLK(m) 0 #endif #define S_ISLNK(m) 0 #define S_ISSOCK(m) S_ISFIFO(m) struct dirent { char d_name[MAX_PATH]; }; struct DIR_s { int want_next; HANDLE hFind; struct dirent result; }; typedef struct DIR_s DIR; static DIR* opendir(const char* path) { HANDLE hFind; WIN32_FIND_DATAA ffd; DIR* dp; char* query; query = malloc(MAX_PATH + 1); if(!query){ errno = ENOMEM; return NULL; } query[0] = 0; strncat(query, path, MAX_PATH); strncat(query, "\\*", MAX_PATH); query[MAX_PATH] = 0; hFind = FindFirstFileA(query, &ffd); if(hFind == INVALID_HANDLE_VALUE){ switch(GetLastError()){ case ERROR_FILE_NOT_FOUND: errno = ENOENT; break; default: errno = EACCES; break; } return NULL; } free(query); dp = malloc(sizeof(DIR)); if(!dp){ errno = ENOMEM; return NULL; } dp->hFind = hFind; strncpy(dp->result.d_name, ffd.cFileName, MAX_PATH); dp->want_next = 0; return dp; } static struct dirent *readdir(DIR *dp) { BOOL b; WIN32_FIND_DATAA ffd; if(dp->want_next){ /* Query the next file */ b = FindNextFile(dp->hFind, &ffd); if(! b){ return NULL; } strncpy(dp->result.d_name, ffd.cFileName, MAX_PATH); } dp->want_next = 1; return &dp->result; } static int closedir(DIR *dp) { BOOL b; b = FindClose(dp->hFind); if(! b){ errno = EBADF; return -1; } free(dp); return 0; }