diff --git a/toolbox/fs_spec.cpp b/toolbox/fs_spec.cpp index c9822ea..b571092 100644 --- a/toolbox/fs_spec.cpp +++ b/toolbox/fs_spec.cpp @@ -2,8 +2,11 @@ #include #include -#include -#include + + +#include + +namespace fs = std::experimental::filesystem; namespace OS { @@ -31,13 +34,12 @@ namespace OS { int32_t FSSpecManager::IDForCWD() { - char buffer[MAXPATHLEN]; - char *cp; - cp = getcwd(buffer, sizeof(buffer)); - if (cp < 0) return 0; + std::error_code ec; + fs::path p = fs::current_path(ec); + if (ec) return 0; - std::string path(cp); + std::string path(p.generic_u8string()); return FSSpecManager::IDForPath(std::move(path), true); } diff --git a/toolbox/os.cpp b/toolbox/os.cpp index 2a92221..7c30328 100644 --- a/toolbox/os.cpp +++ b/toolbox/os.cpp @@ -39,6 +39,10 @@ #include +#include + +namespace fs = std::experimental::filesystem; + #include #include #include @@ -465,8 +469,6 @@ namespace OS _ioDirID = 48, }; - struct stat st; - bool htrap = trap & 0x0200; const char *func = htrap ? "HDelete" : "Delete"; @@ -494,21 +496,10 @@ namespace OS Log(" %s(%s)\n", func, sname.c_str()); - int ok; - - ok = ::lstat(sname.c_str(), &st); - if (ok == 0) - { - if (S_ISDIR(st.st_mode)) - ok = ::rmdir(sname.c_str()); - else - ok = ::unlink(sname.c_str()); - } - - if (ok < 0) - d0 = macos_error_from_errno(); - else - d0 = 0; + std::error_code ec; + if (fs::remove(sname, ec)) d0 = 0; + else if (ec) d0 = macos_error_from_errno(ec); + else d0 = MacOS::fnfErr; memoryWriteWord(d0, parm + _ioResult); return d0; diff --git a/toolbox/os_hfs_dispatch.cpp b/toolbox/os_hfs_dispatch.cpp index fd531f7..d850402 100644 --- a/toolbox/os_hfs_dispatch.cpp +++ b/toolbox/os_hfs_dispatch.cpp @@ -33,13 +33,14 @@ #include #include #include +#include #include #include #include #include -#include -#include + +#include #include @@ -63,6 +64,8 @@ using ToolBox::Log; using MacOS::macos_error_from_errno; +namespace fs = std::experimental::filesystem; + namespace OS { uint16_t PBGetWDInfo(uint32_t parm) @@ -328,11 +331,8 @@ namespace OS { std::string sname = FSSpecManager::PathForID(ioDirID); if (sname.empty()) { - char buffer[MAXPATHLEN]; - char *cp; - - cp = getcwd(buffer, sizeof(buffer)); - sname = cp ? cp : "."; + auto path = fs::current_path(); + sname = path.empty() ? "." : path.generic_u8string(); } d0 = CatInfoByName(sname, parm); @@ -366,46 +366,26 @@ namespace OS { sname = OS::realpath(sname); // if sname == "", error... - DIR *dp; - struct dirent *dir; - dp = opendir(sname.c_str()); - if (!dp) { - d0 = macos_error_from_errno(); + fs::directory_iterator dir(sname); + std::vector names(fs::begin(dir), fs::end(dir)); + + if (ioFDirIndex >= names.size()) { + d0 = MacOS::fnfErr; // end of dir error? memoryWriteWord(d0, parm + _ioResult); return d0; } - while ((dir = readdir(dp))) { - if (dir->d_name[0] == '.') { - if (!strcmp(dir->d_name, ".")) continue; - if (!strcmp(dir->d_name, "..")) continue; - } -#ifdef HAVE_DIRENT_D_NAMLEN - if (dir->d_namlen > 255) continue; // too long! -#else - if (strlen(dir->d_name) > 255) continue; -#endif - if (--ioFDirIndex == 0) break; - } + // alphabetical order... + std::sort(names.begin(), names.end()); - if (!dir) { - closedir(dp); - d0 = MacOS::fnfErr; - memoryWriteWord(d0, parm + _ioResult); - return d0; - } + auto e = names[ioFDirIndex - 1]; if (ioNamePtr) { - ToolBox::WritePString(ioNamePtr, dir->d_name); + ToolBox::WritePString(ioNamePtr, e.filename().generic_u8string()); } - sname.push_back('/'); - sname.append(dir->d_name); - closedir(dp); - - - d0 = CatInfoByName(sname, parm); + d0 = CatInfoByName(e.generic_u8string(), parm); } memoryWriteWord(d0, parm + _ioResult); diff --git a/toolbox/os_highlevel.cpp b/toolbox/os_highlevel.cpp index fd18a7f..f4c0021 100644 --- a/toolbox/os_highlevel.cpp +++ b/toolbox/os_highlevel.cpp @@ -43,6 +43,10 @@ #include +#include + +namespace fs = std::experimental::filesystem; + #include #include #include @@ -81,6 +85,10 @@ namespace OS { // MacOS: -> { -1, 1, "MacOS" } // MacOS:dumper -> {-1, 2 "dumper"} +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + std::string realpath(const std::string &path) { char buffer[PATH_MAX + 1]; @@ -340,7 +348,6 @@ namespace OS { */ uint32_t spec; - struct stat st; StackFrame<4>(spec); @@ -348,20 +355,11 @@ namespace OS { Log(" FSpDelete(%s)\n", sname.c_str()); + std::error_code ec; - if (::lstat(sname.c_str(), &st) < 0) - return macos_error_from_errno(); - - int ok = 0; - if (S_ISDIR(st.st_mode)) - ok = ::rmdir(sname.c_str()); - else - ok = ::unlink(sname.c_str()); - - if (ok < 0) - return macos_error_from_errno(); - - return 0; + if (fs::remove(sname, ec)) return 0; + if (ec) return macos_error_from_errno(ec); + return MacOS::fnfErr; } @@ -388,20 +386,19 @@ namespace OS { Log(" ResolveAliasFile(%s)\n", path.c_str()); - struct stat st; - int rv; - rv = ::stat(path.c_str(), &st); - if (rv < 0) - { + std::error_code ec; + fs::file_status st = fs::status(path, ec); + + if (ec) { if (wasAliased) memoryWriteWord(0, wasAliased); if (targetIsFolder) memoryWriteWord(0, targetIsFolder); - return macos_error_from_errno(); + return macos_error_from_errno(ec); } if (targetIsFolder) - memoryWriteWord(S_ISDIR(st.st_mode) ? 1 : 0, targetIsFolder); + memoryWriteWord(fs::is_directory(st) ? 1 : 0, targetIsFolder); // don't bother pretending a soft link is an alias. if (wasAliased) memoryWriteWord(0, wasAliased);