chibi-scheme/lib/chibi/filesystem_win32_shim.c
2017-12-13 22:00:07 +09:00

104 lines
2.2 KiB
C

/* Win32 shim for (chibi filesystem) */
#include <windows.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <direct.h>
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;
}