diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index 1505682f11..6df91a2732 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -58,21 +58,23 @@ typedef struct _mp_obj_vfs_posix_t { } mp_obj_vfs_posix_t; STATIC const char *vfs_posix_get_path_str(mp_obj_vfs_posix_t *self, mp_obj_t path) { - if (self->root_len == 0) { - return mp_obj_str_get_str(path); + const char *path_str = mp_obj_str_get_str(path); + if (self->root_len == 0 || path_str[0] != '/') { + return path_str; } else { - self->root.len = self->root_len; - vstr_add_str(&self->root, mp_obj_str_get_str(path)); + self->root.len = self->root_len - 1; + vstr_add_str(&self->root, path_str); return vstr_null_terminated_str(&self->root); } } STATIC mp_obj_t vfs_posix_get_path_obj(mp_obj_vfs_posix_t *self, mp_obj_t path) { - if (self->root_len == 0) { + const char *path_str = mp_obj_str_get_str(path); + if (self->root_len == 0 || path_str[0] != '/') { return path; } else { - self->root.len = self->root_len; - vstr_add_str(&self->root, mp_obj_str_get_str(path)); + self->root.len = self->root_len - 1; + vstr_add_str(&self->root, path_str); return mp_obj_new_str(self->root.buf, self->root.len); } } diff --git a/tests/extmod/vfs_posix_paths.py b/tests/extmod/vfs_posix_paths.py new file mode 100644 index 0000000000..8cdad77068 --- /dev/null +++ b/tests/extmod/vfs_posix_paths.py @@ -0,0 +1,73 @@ +# Test for VfsPosix with relative paths + +try: + import os + + os.VfsPosix +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +# We need a directory for testing that doesn't already exist. +# Skip the test if it does exist. +temp_dir = "vfs_posix_paths_test_dir" +try: + import os + + os.stat(temp_dir) + print("SKIP") + raise SystemExit +except OSError: + pass + +curdir = os.getcwd() +os.mkdir(temp_dir) + +# construct new VfsPosix with absolute path argument +temp_dir_abs = os.getcwd() + os.sep + temp_dir +vfs = os.VfsPosix(temp_dir_abs) +# when VfsPosix is used the intended way via os.mount(), it can only be called +# with relative paths when the CWD is inside or at its root, so simulate that +os.chdir(temp_dir_abs) +vfs.mkdir("subdir") +vfs.mkdir("subdir/one") +print('listdir("/"):', sorted(i[0] for i in vfs.ilistdir("/"))) +print('listdir("."):', sorted(i[0] for i in vfs.ilistdir("."))) +print('getcwd() in {"", "/"}:', vfs.getcwd() in {"", "/"}) +print('chdir("subdir"):', vfs.chdir("subdir")) +print("getcwd():", vfs.getcwd()) +print('mkdir("two"):', vfs.mkdir("two")) +f = vfs.open("file.py", "w") +f.write("print('hello')") +f.close() +print('listdir("/"):', sorted(i[0] for i in vfs.ilistdir("/"))) +print('listdir("/subdir"):', sorted(i[0] for i in vfs.ilistdir("/subdir"))) +print('listdir("."):', sorted(i[0] for i in vfs.ilistdir("."))) +try: + f = vfs.open("/subdir/file.py", "r") + print(f.read()) + f.close() +except Exception as e: + print(e) +import sys + +sys.path.insert(0, "") +try: + import file + + print(file) +except Exception as e: + print(e) +del sys.path[0] +vfs.remove("file.py") +vfs.rmdir("two") +vfs.rmdir("/subdir/one") +vfs.chdir("/") +vfs.rmdir("/subdir") + +# done with vfs, restore CWD +os.chdir(curdir) + +# rmdir +os.rmdir(temp_dir) +print(temp_dir in os.listdir()) diff --git a/tests/extmod/vfs_posix_paths.py.exp b/tests/extmod/vfs_posix_paths.py.exp new file mode 100644 index 0000000000..5828453c92 --- /dev/null +++ b/tests/extmod/vfs_posix_paths.py.exp @@ -0,0 +1,13 @@ +listdir("/"): ['subdir'] +listdir("."): ['subdir'] +getcwd() in {"", "/"}: True +chdir("subdir"): None +getcwd(): subdir +mkdir("two"): None +listdir("/"): ['subdir'] +listdir("/subdir"): ['file.py', 'one', 'two'] +listdir("."): ['file.py', 'one', 'two'] +print('hello') +hello + +False