diff --git a/src/tools/fs_shell/command_cp.cpp b/src/tools/fs_shell/command_cp.cpp index b86f8cb0da..18855c133e 100644 --- a/src/tools/fs_shell/command_cp.cpp +++ b/src/tools/fs_shell/command_cp.cpp @@ -22,6 +22,7 @@ #include "fssh_fs_attr.h" #include "fssh_stat.h" #include "fssh_string.h" +#include "fssh_unistd.h" #include "path_util.h" #include "stat_util.h" #include "syscalls.h" @@ -136,7 +137,7 @@ public: virtual ~HostNode() { if (fFD >= 0) - close(fFD); + fssh_close(fFD); if (fAttrDir) fs_close_attr_dir(fAttrDir); } @@ -340,40 +341,36 @@ public: virtual fssh_status_t Open(const char *path, int openMode, Node *&_node) { // open the node - int fd = open(path, to_platform_open_mode(openMode)); + int fd = fssh_open(path, openMode); if (fd < 0) return fssh_get_errno(); // stat the node - struct stat st; - if (fstat(fd, &st) < 0) { - close(fd); + struct fssh_stat st; + if (fssh_fstat(fd, &st) < 0) { + fssh_close(fd); return fssh_get_errno(); } // check the node type and create the node HostNode *node = NULL; - switch (st.st_mode & S_IFMT) { - case S_IFLNK: + switch (st.fssh_st_mode & FSSH_S_IFMT) { + case FSSH_S_IFLNK: node = new HostSymLink; break; - case S_IFREG: + case FSSH_S_IFREG: node = new HostFile; break; - case S_IFDIR: + case FSSH_S_IFDIR: node = new HostDirectory; break; default: - close(fd); + fssh_close(fd); return FSSH_EINVAL; } - // convert the stat - struct fssh_stat myst; - from_platform_stat(&st, &myst); - // init the node - fssh_status_t error = node->Init(path, fd, myst); + fssh_status_t error = node->Init(path, fd, st); // the node receives ownership of the FD if (error != FSSH_B_OK) { delete node; @@ -385,26 +382,23 @@ public: } virtual fssh_status_t CreateFile(const char *path, - const struct fssh_stat &myst, File *&_file) + const struct fssh_stat &st, File *&_file) { - struct stat st; - to_platform_stat(&myst, &st); - // create the file - int fd = creat(path, st.st_mode & S_IUMSK); + int fd = fssh_creat(path, st.fssh_st_mode & FSSH_S_IUMSK); if (fd < 0) return fssh_get_errno(); // apply the other stat fields fssh_status_t error = _ApplyStat(fd, st); if (error != FSSH_B_OK) { - close(fd); + fssh_close(fd); return error; } // create the object HostFile *file = new HostFile; - error = file->Init(path, fd, myst); + error = file->Init(path, fd, st); if (error != FSSH_B_OK) { delete file; return error; @@ -415,30 +409,27 @@ public: } virtual fssh_status_t CreateDirectory(const char *path, - const struct fssh_stat &myst, Directory *&_dir) + const struct fssh_stat &st, Directory *&_dir) { - struct stat st; - to_platform_stat(&myst, &st); - // create the dir - if (mkdir(path, st.st_mode & S_IUMSK) < 0) + if (fssh_mkdir(path, st.fssh_st_mode & FSSH_S_IUMSK) < 0) return fssh_get_errno(); // open the dir node - int fd = open(path, O_RDONLY | O_NOTRAVERSE); + int fd = fssh_open(path, FSSH_O_RDONLY | FSSH_O_NOTRAVERSE); if (fd < 0) return fssh_get_errno(); // apply the other stat fields fssh_status_t error = _ApplyStat(fd, st); if (error != FSSH_B_OK) { - close(fd); + fssh_close(fd); return error; } // create the object HostDirectory *dir = new HostDirectory; - error = dir->Init(path, fd, myst); + error = dir->Init(path, fd, st); if (error != FSSH_B_OK) { delete dir; return error; @@ -449,30 +440,27 @@ public: } virtual fssh_status_t CreateSymLink(const char *path, const char *linkTo, - const struct fssh_stat &myst, SymLink *&_link) + const struct fssh_stat &st, SymLink *&_link) { - struct stat st; - to_platform_stat(&myst, &st); - // create the link if (symlink(linkTo, path) < 0) return fssh_get_errno(); // open the symlink node - int fd = open(path, O_RDONLY | O_NOTRAVERSE); + int fd = fssh_open(path, FSSH_O_RDONLY | FSSH_O_NOTRAVERSE); if (fd < 0) return fssh_get_errno(); // apply the other stat fields fssh_status_t error = _ApplyStat(fd, st); if (error != FSSH_B_OK) { - close(fd); + fssh_close(fd); return error; } // create the object HostSymLink *link = new HostSymLink; - error = link->Init(path, fd, myst); + error = link->Init(path, fd, st); if (error != FSSH_B_OK) { delete link; return error; @@ -485,13 +473,13 @@ public: virtual fssh_status_t Unlink(const char *path) { - if (unlink(path) < 0) + if (fssh_unlink(path) < 0) return fssh_get_errno(); return FSSH_B_OK; } private: - fssh_status_t _ApplyStat(int fd, const struct stat &st) + fssh_status_t _ApplyStat(int fd, const struct fssh_stat &st) { // TODO: Set times... return FSSH_B_OK; diff --git a/src/tools/fs_shell/fcntl.cpp b/src/tools/fs_shell/fcntl.cpp index c41944276d..1c2cd0a591 100644 --- a/src/tools/fs_shell/fcntl.cpp +++ b/src/tools/fs_shell/fcntl.cpp @@ -8,12 +8,20 @@ #include #include +#include "fssh_errno.h" #include "stat_util.h" using namespace FSShell; +#ifndef __BEOS__ + // The _kern_open() defined in libroot_build.so. + extern "C" int _kern_open(int fd, const char *path, int openMode, + int perms); +#endif + + int fssh_open(const char *pathname, int oflags, ...) { @@ -27,8 +35,26 @@ fssh_open(const char *pathname, int oflags, ...) va_end(args); -// TODO: That's not perfect yet: We should use open() on BeOS compatible -// platforms and _kern_open() otherwise. - return open(pathname, to_platform_open_mode(oflags), - to_platform_mode(mode)); + // Use the _kern_open() defined in libroot on BeOS incompatible systems. + // Required for proper attribute emulation support. + #if __BEOS__ + return open(pathname, to_platform_open_mode(oflags), + to_platform_mode(mode)); + #else + int fd = _kern_open(-1, pathname, to_platform_open_mode(oflags), + to_platform_mode(mode)); + if (fd < 0) { + fssh_set_errno(fd); + return -1; + } + + return fd; + #endif +} + + +int +fssh_creat(const char *path, fssh_mode_t mode) +{ + return fssh_open(path, FSSH_O_WRONLY | FSSH_O_CREAT | FSSH_O_TRUNC, mode); } diff --git a/src/tools/fs_shell/fd.cpp b/src/tools/fs_shell/fd.cpp index c0b1075391..6a05ba2603 100644 --- a/src/tools/fs_shell/fd.cpp +++ b/src/tools/fs_shell/fd.cpp @@ -458,17 +458,11 @@ common_close(int fd, bool kernel) return FSSH_B_OK; } -} // namespace FSShell - - // #pragma mark - // Kernel calls -using namespace FSShell; - - fssh_ssize_t _kern_read(int fd, fssh_off_t pos, void *buffer, fssh_size_t length) { @@ -735,3 +729,4 @@ _kern_dup2(int ofd, int nfd) return dup2_fd(ofd, nfd, true); } +} // namespace FSShell diff --git a/src/tools/fs_shell/stat.cpp b/src/tools/fs_shell/stat.cpp index a5a935c28b..16ea10f669 100644 --- a/src/tools/fs_shell/stat.cpp +++ b/src/tools/fs_shell/stat.cpp @@ -13,6 +13,14 @@ using FSShell::from_platform_stat; +using FSShell::to_platform_mode; + + +int +fssh_mkdir(const char *path, fssh_mode_t mode) +{ + return mkdir(path, to_platform_mode(mode)); +} int diff --git a/src/tools/fs_shell/syscalls.h b/src/tools/fs_shell/syscalls.h index acab6220f4..4d3338e391 100644 --- a/src/tools/fs_shell/syscalls.h +++ b/src/tools/fs_shell/syscalls.h @@ -11,6 +11,9 @@ struct fssh_iovec; +namespace FSShell { + + // defined in vfs.cpp fssh_dev_t _kern_mount(const char *path, const char *device, const char *fsName, uint32_t flags, const char *args, @@ -89,4 +92,8 @@ fssh_status_t _kern_close(int fd); int _kern_dup(int fd); int _kern_dup2(int ofd, int nfd); + +} // namespace FSShell + + #endif // _FSSH_SYSCALLS_H diff --git a/src/tools/fs_shell/unistd.cpp b/src/tools/fs_shell/unistd.cpp index 1eb0d3b40f..f9964d21f1 100644 --- a/src/tools/fs_shell/unistd.cpp +++ b/src/tools/fs_shell/unistd.cpp @@ -27,6 +27,12 @@ #endif +#ifndef __BEOS__ + // The _kern_close() defined in libroot_build.so. + extern "C" status_t _kern_close(int fd); +#endif + + #ifdef HAIKU_HOST_PLATFORM_LINUX static bool @@ -67,7 +73,20 @@ get_partition_size(int fd, off_t maxSize) int fssh_close(int fd) { - return close(fd); + // Use the _kern_close() defined in libroot on BeOS incompatible systems. + // Required for proper attribute emulation support. + #if __BEOS__ + return close(fd); + #else + return _kern_close(fd); + #endif +} + + +int +fssh_unlink(const char *name) +{ + return unlink(name); } diff --git a/src/tools/fs_shell/vfs.cpp b/src/tools/fs_shell/vfs.cpp index 7c64a175bd..f171e408ff 100644 --- a/src/tools/fs_shell/vfs.cpp +++ b/src/tools/fs_shell/vfs.cpp @@ -4551,16 +4551,10 @@ err: } -} // namespace FSShell - - // #pragma mark - // Calls from within the kernel -using namespace FSShell; - - fssh_dev_t _kern_mount(const char *path, const char *device, const char *fsName, uint32_t flags, const char *args, fssh_size_t argsLength) @@ -5208,3 +5202,4 @@ _kern_initialize_volume(const char* fsName, const char *partition, return status; } +} // namespace FSShell