diff --git a/toolbox/os.cpp b/toolbox/os.cpp index 4e9a7c3..41df567 100644 --- a/toolbox/os.cpp +++ b/toolbox/os.cpp @@ -608,6 +608,8 @@ namespace OS _ioDirID = 48, }; + struct stat st; + bool htrap = trap & 0x0200; const char *func = htrap ? "HDelete" : "Delete"; @@ -635,7 +637,17 @@ namespace OS Log(" %s(%s)\n", func, sname.c_str()); - int ok = ::unlink(sname.c_str()); + int ok; + + ok = ::stat(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 diff --git a/toolbox/os_highlevel.cpp b/toolbox/os_highlevel.cpp index 319c263..fddae53 100644 --- a/toolbox/os_highlevel.cpp +++ b/toolbox/os_highlevel.cpp @@ -92,6 +92,14 @@ namespace OS { return std::string(cp); } + std::string ReadFSSpec(uint32_t spec) { + if (!spec) return ""; + + int parentID = memoryReadLong(spec + 2); + std::string sname = ToolBox::ReadPString(spec + 6, false); + return OS::FSSpecManager::ExpandPath(sname, parentID); + } + uint16_t FSMakeFSSpec(void) { // FSMakeFSSpec(vRefNum: Integer; dirID: LongInt; fileName: Str255; VAR spec: FSSpec): OSErr; @@ -309,6 +317,50 @@ namespace OS { + + uint16_t FSpDelete(void) + { + // FUNCTION FSpDelete (spec: FSSpec): OSErr; + + /* + * The FSpDelete function removes a file or directory. If the + * specified target is a file, both forks of the file are + * deleted. The file ID reference, if any, is removed. + * + * A file must be closed before you can delete it. Similarly, a + * directory must be empty before you can delete it. If you + * attempt to delete an open file or a nonempty directory, + * FSpDelete returns the result code fBsyErr. FSpDelete also + * returns the result code fBsyErr if the directory has an open + * working directory associated with it. + */ + + uint32_t spec; + struct stat st; + + StackFrame<4>(spec); + + std::string sname = ReadFSSpec(spec); + + Log(" FSpDelete(%s)\n", sname.c_str()); + + + if (::stat(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; + } + + uint16_t ResolveAliasFile() { // FUNCTION ResolveAliasFile (VAR theSpec: FSSpec; @@ -387,6 +439,7 @@ namespace OS { case 0x0001: d0 = FSMakeFSSpec(); break; + case 0x0002: d0 = FSpOpenDF(); break; @@ -395,6 +448,10 @@ namespace OS { d0 = FSpCreate(); break; + case 0x0006: + d0 = FSpDelete(); + break; + case 0x0007: d0 = FSpGetFInfo(); break;