Commit 2180e178 authored by Deomid Ryabkov's avatar Deomid Ryabkov Committed by Cesanta Bot

Allow use of absolute paths on SLFS

If the path starts with /, do not drop it.
There are no directories on SLFS, but use of /pretend/paths/to/files.txt
is common. What we do drop is the ./ prefix (added by mongoose when document_root=.)

PUBLISHED_FROM=5108bc078dfaf8f8afa4db554b4769d9d7b8a103
parent 8fb5e8ef
...@@ -11737,7 +11737,6 @@ int fs_slfs_open(const char *pathname, int flags, mode_t mode) { ...@@ -11737,7 +11737,6 @@ int fs_slfs_open(const char *pathname, int flags, mode_t mode) {
_u32 am = 0; _u32 am = 0;
fi->size = (size_t) -1; fi->size = (size_t) -1;
if (pathname[0] == '/') pathname++;
int rw = (flags & 3); int rw = (flags & 3);
if (rw == O_RDONLY) { if (rw == O_RDONLY) {
SlFsFileInfo_t sl_fi; SlFsFileInfo_t sl_fi;
...@@ -11861,10 +11860,6 @@ int fs_slfs_unlink(const char *filename) { ...@@ -11861,10 +11860,6 @@ int fs_slfs_unlink(const char *filename) {
return set_errno(sl_fs_to_errno(sl_FsDel((const _u8 *) filename, 0))); return set_errno(sl_fs_to_errno(sl_FsDel((const _u8 *) filename, 0)));
} }
int fs_slfs_rename(const char *from, const char *to) {
return set_errno(ENOTSUP);
}
void fs_slfs_set_new_file_size(const char *name, size_t size) { void fs_slfs_set_new_file_size(const char *name, size_t size) {
int i; int i;
for (i = 0; i < MAX_OPEN_SLFS_FILES; i++) { for (i = 0; i < MAX_OPEN_SLFS_FILES; i++) {
...@@ -11890,6 +11885,7 @@ void fs_slfs_set_new_file_size(const char *name, size_t size) { ...@@ -11890,6 +11885,7 @@ void fs_slfs_set_new_file_size(const char *name, size_t size) {
(defined(MG_FS_SLFS) || defined(MG_FS_SPIFFS)) (defined(MG_FS_SLFS) || defined(MG_FS_SPIFFS))
#include <errno.h> #include <errno.h>
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -11930,17 +11926,20 @@ int set_errno(int e) { ...@@ -11930,17 +11926,20 @@ int set_errno(int e) {
return (e == 0 ? 0 : -1); return (e == 0 ? 0 : -1);
} }
static int is_sl_fname(const char *fname) { static const char *drop_dir(const char *fname, bool *is_slfs) {
return strncmp(fname, "SL:", 3) == 0; *is_slfs = (strncmp(fname, "SL:", 3) == 0);
} if (*is_slfs) fname += 3;
/* Drop "./", if any */
static const char *sl_fname(const char *fname) { if (fname[0] == '.' && fname[1] == '/') {
return fname + 3; fname += 2;
} }
/*
static const char *drop_dir(const char *fname) { * Drop / if it is the only one in the path.
if (*fname == '.') fname++; * This allows use of /pretend/directories but serves /file.txt as normal.
if (*fname == '/') fname++; */
if (fname[0] == '/' && strchr(fname + 1, '/') == NULL) {
fname++;
}
return fname; return fname;
} }
...@@ -11975,31 +11974,30 @@ int open(const char *pathname, unsigned flags, int mode) { ...@@ -11975,31 +11974,30 @@ int open(const char *pathname, unsigned flags, int mode) {
int _open(const char *pathname, int flags, mode_t mode) { int _open(const char *pathname, int flags, mode_t mode) {
#endif #endif
int fd = -1; int fd = -1;
pathname = drop_dir(pathname); bool is_sl;
if (is_sl_fname(pathname)) { const char *fname = drop_dir(pathname, &is_sl);
if (is_sl) {
#ifdef MG_FS_SLFS #ifdef MG_FS_SLFS
fd = fs_slfs_open(sl_fname(pathname), flags, mode); fd = fs_slfs_open(fname, flags, mode);
if (fd >= 0) fd += SLFS_FD_BASE; if (fd >= 0) fd += SLFS_FD_BASE;
#endif #endif
} else { } else {
#ifdef CC3200_FS_SPIFFS #ifdef CC3200_FS_SPIFFS
fd = fs_spiffs_open(pathname, flags, mode); fd = fs_spiffs_open(fname, flags, mode);
if (fd >= 0) fd += SPIFFS_FD_BASE; if (fd >= 0) fd += SPIFFS_FD_BASE;
#endif #endif
} }
DBG(("open(%s, 0x%x) = %d", pathname, flags, fd)); DBG(("open(%s, 0x%x) = %d, fname = %s", pathname, flags, fd, fname));
return fd; return fd;
} }
int _stat(const char *pathname, struct stat *st) { int _stat(const char *pathname, struct stat *st) {
int res = -1; int res = -1;
const char *fname = pathname; bool is_sl;
int is_sl = is_sl_fname(pathname); const char *fname = drop_dir(pathname, &is_sl);
if (is_sl) fname = sl_fname(pathname);
fname = drop_dir(fname);
memset(st, 0, sizeof(*st)); memset(st, 0, sizeof(*st));
/* Simulate statting the root directory. */ /* Simulate statting the root directory. */
if (strcmp(fname, "") == 0) { if (fname[0] == '\0' || strcmp(fname, ".") == 0) {
st->st_ino = 0; st->st_ino = 0;
st->st_mode = S_IFDIR | 0777; st->st_mode = S_IFDIR | 0777;
st->st_nlink = 1; st->st_nlink = 1;
...@@ -12182,14 +12180,13 @@ ssize_t _write(int fd, const void *buf, size_t count) { ...@@ -12182,14 +12180,13 @@ ssize_t _write(int fd, const void *buf, size_t count) {
* implementation using _link and _unlink doesn't work for us. * implementation using _link and _unlink doesn't work for us.
*/ */
#if MG_TI_NO_HOST_INTERFACE || defined(_NEWLIB_VERSION) #if MG_TI_NO_HOST_INTERFACE || defined(_NEWLIB_VERSION)
int rename(const char *from, const char *to) { int rename(const char *frompath, const char *topath) {
int r = -1; int r = -1;
from = drop_dir(from); bool is_sl_from, is_sl_to;
to = drop_dir(to); const char *from = drop_dir(frompath, &is_sl_from);
if (is_sl_fname(from) || is_sl_fname(to)) { const char *to = drop_dir(topath, &is_sl_to);
#ifdef MG_FS_SLFS if (is_sl_from || is_sl_to) {
r = fs_slfs_rename(sl_fname(from), sl_fname(to)); set_errno(ENOTSUP);
#endif
} else { } else {
#ifdef CC3200_FS_SPIFFS #ifdef CC3200_FS_SPIFFS
r = fs_spiffs_rename(from, to); r = fs_spiffs_rename(from, to);
...@@ -12201,29 +12198,32 @@ int rename(const char *from, const char *to) { ...@@ -12201,29 +12198,32 @@ int rename(const char *from, const char *to) {
#endif /* MG_TI_NO_HOST_INTERFACE || defined(_NEWLIB_VERSION) */ #endif /* MG_TI_NO_HOST_INTERFACE || defined(_NEWLIB_VERSION) */
#if MG_TI_NO_HOST_INTERFACE #if MG_TI_NO_HOST_INTERFACE
int unlink(const char *filename) { int unlink(const char *pathname) {
#else #else
int _unlink(const char *filename) { int _unlink(const char *pathname) {
#endif #endif
int r = -1; int r = -1;
filename = drop_dir(filename); bool is_sl;
if (is_sl_fname(filename)) { const char *fname = drop_dir(pathname, &is_sl);
if (is_sl) {
#ifdef MG_FS_SLFS #ifdef MG_FS_SLFS
r = fs_slfs_unlink(sl_fname(filename)); r = fs_slfs_unlink(fname);
#endif #endif
} else { } else {
#ifdef CC3200_FS_SPIFFS #ifdef CC3200_FS_SPIFFS
r = fs_spiffs_unlink(filename); r = fs_spiffs_unlink(fname);
#endif #endif
} }
DBG(("unlink(%s) = %d", filename, r)); DBG(("unlink(%s) = %d, fname = %s", pathname, r, fname));
return r; return r;
} }
#ifdef CC3200_FS_SPIFFS /* FailFS does not support listing files. */ #ifdef CC3200_FS_SPIFFS /* FailFS does not support listing files. */
DIR *opendir(const char *dir_name) { DIR *opendir(const char *dir_name) {
DIR *r = NULL; DIR *r = NULL;
if (is_sl_fname(dir_name)) { bool is_sl;
drop_dir(dir_name, &is_sl);
if (is_sl) {
r = NULL; r = NULL;
set_errno(ENOTSUP); set_errno(ENOTSUP);
} else { } else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment