mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-08 16:11:18 +00:00
Implement FS virtualization
This commit is contained in:
1 parent
9346122c29
commit
c2176f969b
28 files changed
+659
-732
No files matched your search
+130
-18
@@ -1,15 +1,20 @@
|
||||
#include "fs.h"
|
||||
|
||||
#if defined(O_READ)
|
||||
#if defined(FOPEN_MAX)
|
||||
static char *posix_realpath(const char *path, char *resolved_path) {
|
||||
#ifdef _WIN32
|
||||
return _fullpath(path, resolved_path, PATH_MAX);
|
||||
return _fullpath(resolved_path, path, _MAX_PATH);
|
||||
#elif MG_ARCH == MG_ARCH_ESP32 || MG_ARCH == MG_ARCH_ESP8266 || \
|
||||
MG_ARCH == MG_ARCH_FREERTOS_TCP
|
||||
if (resolved_path == NULL) resolved_path = malloc(strlen(path) + 1);
|
||||
strcpy(resolved_path, path);
|
||||
return resolved_path;
|
||||
#else
|
||||
return realpath(path, resolved_path);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int posix_stat(const char *path, size_t *size, unsigned *mtime) {
|
||||
static int posix_stat(const char *path, size_t *size, time_t *mtime) {
|
||||
#ifdef _WIN32
|
||||
struct _stati64 st;
|
||||
wchar_t tmp[PATH_MAX];
|
||||
@@ -20,26 +25,133 @@ static int posix_stat(const char *path, size_t *size, unsigned *mtime) {
|
||||
if (stat(path, &st) != 0) return 0;
|
||||
#endif
|
||||
if (size) *size = (size_t) st.st_size;
|
||||
if (mtime) *mtime = (unsigned) st.st_mtime;
|
||||
if (mtime) *mtime = st.st_mtime;
|
||||
return MG_FS_READ | MG_FS_WRITE | (S_ISDIR(st.st_mode) ? MG_FS_DIR : 0);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
struct dirent {
|
||||
char d_name[MAX_PATH];
|
||||
};
|
||||
|
||||
typedef struct win32_dir {
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAW info;
|
||||
struct dirent result;
|
||||
} DIR;
|
||||
|
||||
int gettimeofday(struct timeval *tv, void *tz) {
|
||||
FILETIME ft;
|
||||
unsigned __int64 tmpres = 0;
|
||||
|
||||
if (tv != NULL) {
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
tmpres |= ft.dwHighDateTime;
|
||||
tmpres <<= 32;
|
||||
tmpres |= ft.dwLowDateTime;
|
||||
tmpres /= 10; // convert into microseconds
|
||||
tmpres -= (int64_t) 11644473600000000;
|
||||
tv->tv_sec = (long) (tmpres / 1000000UL);
|
||||
tv->tv_usec = (long) (tmpres % 1000000UL);
|
||||
}
|
||||
(void) tz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len) {
|
||||
int ret;
|
||||
char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p;
|
||||
strncpy(buf, path, sizeof(buf));
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
// Trim trailing slashes. Leave backslash for paths like "X:\"
|
||||
p = buf + strlen(buf) - 1;
|
||||
while (p > buf && p[-1] != ':' && (p[0] == '\\' || p[0] == '/')) *p-- = '\0';
|
||||
memset(wbuf, 0, wbuf_len * sizeof(wchar_t));
|
||||
ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int) wbuf_len);
|
||||
// Convert back to Unicode. If doubly-converted string does not match the
|
||||
// original, something is fishy, reject.
|
||||
WideCharToMultiByte(CP_UTF8, 0, wbuf, (int) wbuf_len, buf2, sizeof(buf2),
|
||||
NULL, NULL);
|
||||
if (strcmp(buf, buf2) != 0) {
|
||||
wbuf[0] = L'\0';
|
||||
ret = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DIR *opendir(const char *name) {
|
||||
DIR *d = NULL;
|
||||
wchar_t wpath[MAX_PATH];
|
||||
DWORD attrs;
|
||||
|
||||
if (name == NULL) {
|
||||
SetLastError(ERROR_BAD_ARGUMENTS);
|
||||
} else if ((d = (DIR *) calloc(1, sizeof(*d))) == NULL) {
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
} else {
|
||||
to_wchar(name, wpath, sizeof(wpath) / sizeof(wpath[0]));
|
||||
attrs = GetFileAttributesW(wpath);
|
||||
if (attrs != 0Xffffffff && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
(void) wcscat(wpath, L"\\*");
|
||||
d->handle = FindFirstFileW(wpath, &d->info);
|
||||
d->result.d_name[0] = '\0';
|
||||
} else {
|
||||
free(d);
|
||||
d = NULL;
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
int closedir(DIR *d) {
|
||||
int result = 0;
|
||||
if (d != NULL) {
|
||||
if (d->handle != INVALID_HANDLE_VALUE)
|
||||
result = FindClose(d->handle) ? 0 : -1;
|
||||
free(d);
|
||||
} else {
|
||||
result = -1;
|
||||
SetLastError(ERROR_BAD_ARGUMENTS);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
struct dirent *readdir(DIR *d) {
|
||||
struct dirent *result = NULL;
|
||||
if (d != NULL) {
|
||||
memset(&d->result, 0, sizeof(d->result));
|
||||
if (d->handle != INVALID_HANDLE_VALUE) {
|
||||
result = &d->result;
|
||||
WideCharToMultiByte(CP_UTF8, 0, d->info.cFileName, -1, result->d_name,
|
||||
sizeof(result->d_name), NULL, NULL);
|
||||
if (!FindNextFileW(d->handle, &d->info)) {
|
||||
FindClose(d->handle);
|
||||
d->handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
} else {
|
||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
} else {
|
||||
SetLastError(ERROR_BAD_ARGUMENTS);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void posix_list(const char *dir, void (*fn)(const char *, void *),
|
||||
void *userdata) {
|
||||
// char path[MG_PATH_MAX], *p = &dir[strlen(dir) - 1], tmp[10];
|
||||
#if MG_ENABLE_DIRLIST
|
||||
struct dirent *dp;
|
||||
DIR *dirp;
|
||||
|
||||
// while (p > dir && *p != '/') *p-- = '\0';
|
||||
if ((dirp = (opendir(dir))) != NULL) {
|
||||
size_t off, n;
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
// Do not show current dir and hidden files
|
||||
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
|
||||
fn(dp->d_name, &st);
|
||||
}
|
||||
closedir(dirp);
|
||||
if ((dirp = (opendir(dir))) == NULL) return;
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue;
|
||||
fn(dp->d_name, userdata);
|
||||
}
|
||||
closedir(dirp);
|
||||
#else
|
||||
(void) dir, (void) fn, (void) userdata;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct mg_fd *posix_open(const char *path, int flags) {
|
||||
@@ -58,14 +170,14 @@ static struct mg_fd *posix_open(const char *path, int flags) {
|
||||
fp = (void *) fopen(path, mode);
|
||||
#endif
|
||||
if (fp == NULL) return NULL;
|
||||
fd = calloc(1, sizeof(*fd));
|
||||
fd = (struct mg_fd *) calloc(1, sizeof(*fd));
|
||||
fd->fd = fp;
|
||||
fd->fs = &mg_fs_posix;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void posix_close(struct mg_fd *fd) {
|
||||
if (fd) fclose((FILE *) fd->fd), free(fd);
|
||||
if (fd != NULL) fclose((FILE *) fd->fd), free(fd);
|
||||
}
|
||||
|
||||
static size_t posix_read(void *fp, void *buf, size_t len) {
|
||||
@@ -91,7 +203,7 @@ static char *posix_realpath(const char *path, char *resolved_path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int posix_stat(const char *path, size_t *size, unsigned *mtime) {
|
||||
static int posix_stat(const char *path, size_t *size, time_t *mtime) {
|
||||
(void) path, (void) size, (void) mtime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user