diff --git a/os/sb/apps/msh/source/paths.c b/os/sb/apps/msh/source/paths.c index 3c8a5ad87..14bd8e220 100644 --- a/os/sb/apps/msh/source/paths.c +++ b/os/sb/apps/msh/source/paths.c @@ -164,6 +164,7 @@ size_t path_add_separator(char *dst, size_t size) { return dn + 1; } +#if 0 /** * @brief Normalizes an absolute path. * @note The destination buffer can be the same of the source buffer. @@ -242,5 +243,6 @@ size_t path_normalize(char *dst, const char *src, size_t size) { n++; } } +#endif /** @} */ diff --git a/os/sb/common/sbsysc.h b/os/sb/common/sbsysc.h index 07dac686f..05c359ec6 100644 --- a/os/sb/common/sbsysc.h +++ b/os/sb/common/sbsysc.h @@ -58,11 +58,13 @@ #define SB_POSIX_CLOSE 2 #define SB_POSIX_DUP 3 #define SB_POSIX_DUP2 4 -#define SB_POSIX_FSTAT 9 -#define SB_POSIX_READ 5 -#define SB_POSIX_WRITE 6 -#define SB_POSIX_LSEEK 7 -#define SB_POSIX_GETDENTS 8 +#define SB_POSIX_FSTAT 5 +#define SB_POSIX_READ 6 +#define SB_POSIX_WRITE 7 +#define SB_POSIX_LSEEK 8 +#define SB_POSIX_GETDENTS 9 +#define SB_POSIX_CHDIR 10 +#define SB_POSIX_GETCWD 11 /** @} */ /*===========================================================================*/ diff --git a/os/sb/host/sbapi.c b/os/sb/host/sbapi.c index 3a2a613b2..fbf5dea3c 100644 --- a/os/sb/host/sbapi.c +++ b/os/sb/host/sbapi.c @@ -980,45 +980,52 @@ void sb_api_stdio(struct port_extctx *ectxp) { switch (ectxp->r0) { case SB_POSIX_OPEN: - ectxp->r0 = sb_posix_open((const char *)ectxp->r1, - ectxp->r2); + ectxp->r0 = (uint32_t)sb_posix_open((const char *)ectxp->r1, + (int)ectxp->r2); break; case SB_POSIX_CLOSE: - ectxp->r0 = sb_posix_close(ectxp->r1); + ectxp->r0 = (uint32_t)sb_posix_close((int)ectxp->r1); break; case SB_POSIX_DUP: - ectxp->r0 = sb_posix_dup((int)ectxp->r1); + ectxp->r0 = (uint32_t)sb_posix_dup((int)ectxp->r1); break; case SB_POSIX_DUP2: - ectxp->r0 = sb_posix_dup2((int)ectxp->r1, - (int)ectxp->r2); + ectxp->r0 = (uint32_t)sb_posix_dup2((int)ectxp->r1, + (int)ectxp->r2); break; case SB_POSIX_FSTAT: - ectxp->r0 = sb_posix_fstat((int)ectxp->r1, - (struct stat *)ectxp->r2); + ectxp->r0 = (uint32_t)sb_posix_fstat((int)ectxp->r1, + (struct stat *)ectxp->r2); break; case SB_POSIX_READ: - ectxp->r0 = sb_posix_read(ectxp->r1, - (void *)ectxp->r2, - (size_t)ectxp->r3); + ectxp->r0 = (uint32_t)sb_posix_read((int)ectxp->r1, + (void *)ectxp->r2, + (size_t)ectxp->r3); break; case SB_POSIX_WRITE: - ectxp->r0 = sb_posix_write(ectxp->r1, - (const void *)ectxp->r2, - (size_t)ectxp->r3); + ectxp->r0 = (uint32_t)sb_posix_write((int)ectxp->r1, + (const void *)ectxp->r2, + (size_t)ectxp->r3); break; case SB_POSIX_LSEEK: - ectxp->r0 = sb_posix_lseek(ectxp->r1, - ectxp->r2, - ectxp->r3); + ectxp->r0 = (uint32_t)sb_posix_lseek((int)ectxp->r1, + (off_t)ectxp->r2, + (int)ectxp->r3); break; case SB_POSIX_GETDENTS: - ectxp->r0 = sb_posix_getdents(ectxp->r1, - (void *)ectxp->r2, - (size_t)ectxp->r3); + ectxp->r0 = (uint32_t)sb_posix_getdents((int)ectxp->r1, + (void *)ectxp->r2, + (size_t)ectxp->r3); + break; + case SB_POSIX_CHDIR: + ectxp->r0 = (uint32_t)sb_posix_chdir((const char *)ectxp->r1); + break; + case SB_POSIX_GETCWD: + ectxp->r0 = (uint32_t)sb_posix_getcwd((char *)ectxp->r1, + (size_t)ectxp->r2); break; default: - ectxp->r0 = CH_RET_ENOSYS; + ectxp->r0 = (uint32_t)CH_RET_ENOSYS; break; } } diff --git a/os/sb/host/sbposix.c b/os/sb/host/sbposix.c index 1461d5ba8..01337fbdf 100644 --- a/os/sb/host/sbposix.c +++ b/os/sb/host/sbposix.c @@ -300,6 +300,28 @@ ssize_t sb_posix_getdents(int fd, void *buf, size_t count) { return (ssize_t)ret; } +int sb_posix_chdir(const char *path) { + sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; + + if (sb_check_string(sbp, (void *)path, VFS_CFG_PATHLEN_MAX + 1) == (size_t)0) { + return CH_RET_EFAULT; + } + + return (int)vfsDrvChangeCurrentDirectory(sbp->config->vfs_driver, path); +} + +int sb_posix_getcwd(char *buf, size_t size) { + sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p; + + if (!sb_is_valid_write_range(sbp, buf, size)) { + return CH_RET_EFAULT; + } + + /* Note, it does not return a pointer to the buffer as required by Posix, + this has to be handled on the user-side library.*/ + return vfsDrvGetCurrentDirectory(sbp->config->vfs_driver, buf, size); +} + #else /* Fallbacks for when there is no VFS.*/ uint32_t sb_posix_open(const char *pathname, uint32_t flags) { diff --git a/os/sb/host/sbposix.h b/os/sb/host/sbposix.h index 4917cc829..744d4c0f5 100644 --- a/os/sb/host/sbposix.h +++ b/os/sb/host/sbposix.h @@ -68,6 +68,8 @@ extern "C" { ssize_t sb_posix_write(int fd, const void *buf, size_t count); off_t sb_posix_lseek(int fd, off_t offset, int whence); ssize_t sb_posix_getdents(int fd, void *buf, size_t count); + int sb_posix_chdir(const char *path); + int sb_posix_getcwd(char *buf, size_t size); #ifdef __cplusplus } #endif diff --git a/os/sb/user/lib/syscalls.c b/os/sb/user/lib/syscalls.c index bc0cfb31d..814dcdceb 100644 --- a/os/sb/user/lib/syscalls.c +++ b/os/sb/user/lib/syscalls.c @@ -148,7 +148,7 @@ __attribute__((used)) int _getdents_r(struct _reent *r, int fd, void *dp, int count) { ssize_t n; - n = sbPosixGetdents(fd, dp, count); + n = sbGetdents(fd, dp, count); if (CH_RET_IS_ERROR(n)) { __errno_r(r) = CH_DECODE_ERROR(n); return -1; diff --git a/os/sb/user/sbuser.h b/os/sb/user/sbuser.h index 325a10209..ca8327d8c 100644 --- a/os/sb/user/sbuser.h +++ b/os/sb/user/sbuser.h @@ -216,8 +216,7 @@ extern "C" { * @param[in] flags open mode * @return The file descriptor or an error. */ -static inline int sbOpen(const char *pathname, - int flags) { +static inline int sbOpen(const char *pathname, int flags) { __syscall3r(0, SB_POSIX_OPEN, pathname, flags); return (int)r0; @@ -323,12 +322,37 @@ static inline off_t sbSeek(int fd, off_t offset, int whence) { * @param[in] count number of bytes * @return The number of bytes really transferred or an error. */ -static inline ssize_t sbPosixGetdents(int fd, void *buf, size_t count) { +static inline ssize_t sbGetdents(int fd, void *buf, size_t count) { __syscall4r(0, SB_POSIX_GETDENTS, fd, buf, count); return (ssize_t)r0; } +/** + * @brief Posix-style change current directory. + * + * @param[in] path new current path + * @return Operation result. + */ +static inline int sbChdir(const char *path) { + + __syscall2r(0, SB_POSIX_CHDIR, path); + return (int)r0; +} + +/** + * @brief Posix-style get current directory. + * + * @param[in] buf path buffer + * @param[in] size path buffer size + * @return Operation result. + */ +static inline int sbGetcwd(char *buf, size_t size) { + + __syscall3r(0, SB_POSIX_GETCWD, buf, size); + return (int)r0; +} + /** * @brief Terminates the sandbox. *