diff --git a/toolbox/os.cpp b/toolbox/os.cpp index 15f34de..06e6976 100644 --- a/toolbox/os.cpp +++ b/toolbox/os.cpp @@ -1,24 +1,55 @@ #include "os.h" - +#include "toolbox.h" #include #include #include #include +#include #include #include #include #include +namespace { + + using namespace OS; + + uint16_t errno_to_oserr(int xerrno) + { + switch (xerrno) + { + case EBADF: return rfNumErr; + case EIO: return ioErr; + case EACCES: return permErr; + case ENOENT: return fnfErr; + case ENOTDIR: return dirNFErr; + case EISDIR: return notAFileErr; + case ENOTSUP: return extFSErr; + case EROFS: return wPrErr; + + case EDQUOT: return dskFulErr; + case ENOSPC: return dskFulErr; + + + default: + return ioErr; + } + + } +} + namespace OS { uint16_t GetFileInfo(uint16_t trap) { - uint32_t parm = cpuGetAReg(0); + uint16_t d0; + + uint32_t parm = cpuGetAReg(0); fprintf(stderr, "%04x GetFileInfo(%08x)\n", trap, parm); @@ -39,12 +70,7 @@ namespace OS return bdNamErr; } - int l = memoryReadByte(ioNamePtr); - sname.reserve(l); - for (unsigned i = 0; i < l; ++i) - { - sname.push_back(memoryReadByte(ioNamePtr + 1 + i)); - } + sname = ToolBox::ReadPString(ioNamePtr); // todo -- how are absolute, relative, etc paths handled... @@ -53,8 +79,10 @@ namespace OS if (::stat(sname.c_str(), &st) < 0) { - memoryWriteWord(bdNamErr, parm + 16); - return fnfErr; + d0 = errno_to_oserr(errno); + + memoryWriteWord(d0, parm + 16); + return d0; } // finder info @@ -126,4 +154,79 @@ namespace OS return 0; } + uint16_t SetFileInfo(uint16_t trap) + { + std::string sname; + uint16_t d0; + + + uint32_t parm = cpuGetAReg(0); + + fprintf(stderr, "%04x SetFileInfo(%08x)\n", trap, parm); + + uint32_t ioCompletion = memoryReadLong(parm + 12); + uint32_t ioNamePtr = memoryReadLong(parm + 18); + uint16_t ioVRefNum = memoryReadWord(parm + 22); + uint8_t ioFVersNum = memoryReadByte(parm + 26); + //int16_t ioFDirIndex = memoryReadWord(parm + 28); + + // + 32 = finder data - 16 bytes. + + uint32_t ioFlCrDat = memoryReadLong(parm + 72); + uint32_t ioFlMdDat = memoryReadLong(parm + 76); + + // currently, only sets finder info. + + if (!ioNamePtr) + { + memoryWriteWord(bdNamErr, parm + 16); + return bdNamErr; + } + + sname = ToolBox::ReadPString(ioNamePtr); + + // check if the file actually exists + { + struct stat st; + int ok; + + ok = ::stat(sname.c_str(), &st); + if (ok < 0) + { + d0 = errno_to_oserr(errno); + memoryWriteWord(d0, parm + 16); + return d0; + } + + + } + + // finder info is actually 32 bytes, so read and update the first 16. + { + uint8_t buffer[32]; + int ok; + + std::memset(buffer, 0, sizeof(buffer)); + + ok = ::getxattr(sname.c_str(), XATTR_FINDERINFO_NAME, buffer, 32, 0, 0); + + // only 16 bytes copied. + std::memcpy(buffer, memoryPointer(parm + 32), 16); + + ok = ::setxattr(sname.c_str(), XATTR_FINDERINFO_NAME, buffer, 32, 0, 0); + + if (ok < 0) + { + d0 = errno_to_oserr(errno); + memoryWriteWord(d0, parm + 16); + return d0; + } + } + + d0 = 0; + memoryWriteWord(d0, parm + 16); + return d0; + } + + } \ No newline at end of file diff --git a/toolbox/os.h b/toolbox/os.h index ddeefe4..3d71a37 100644 --- a/toolbox/os.h +++ b/toolbox/os.h @@ -74,7 +74,7 @@ namespace OS wrgVolTypErr = -123, /*Wrong volume type error [operation not supported for MFS]*/ volGoneErr = -124 /*Server volume has been disconnected.*/ }; - + enum { fidNotFound = -1300, /*no file thread exists.*/ fidExists = -1301, /*file id already exists*/ @@ -100,6 +100,7 @@ namespace OS uint16_t GetFileInfo(uint16_t trap); + uint16_t SetFileInfo(uint16_t trap); } #endif diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index 8904478..0cd55c7 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -11,11 +11,17 @@ #include "mm.h" #include "os.h" +#include + // yuck. TST.W d0 extern "C" void cpuSetFlagsNZ00NewW(UWO res); namespace ToolBox { + + + + void dispatch(uint16_t trap) { // todo -- check/remove extra bits for save a0, toolglue, etc. @@ -26,6 +32,9 @@ namespace ToolBox { case 0xA00C: d0 = OS::GetFileInfo(trap); break; + case 0xa00d: + d0 = OS::SetFileInfo(trap); + break; // BlockMove (sourcePtr,destPtr: Ptr; byteCount: Size); case 0xa02e: @@ -62,4 +71,31 @@ namespace ToolBox { cpuSetFlagsNZ00NewW(d0); } + std::string ReadCString(uint32_t address) + { + std::string tmp; + + if (address) + { + tmp.assign((char *)memoryPointer(address)); + } + + return tmp; + } + + std::string ReadPString(uint32_t address) + { + std::string tmp; + + if (address) + { + unsigned length = memoryReadByte(address); + + tmp.assign((char *)memoryPointer(address + 1), length); + } + + return tmp; + } + + } \ No newline at end of file diff --git a/toolbox/toolbox.h b/toolbox/toolbox.h index 3bc2471..600391c 100644 --- a/toolbox/toolbox.h +++ b/toolbox/toolbox.h @@ -1,9 +1,15 @@ #ifndef __mpw_toolbox_h__ #define __mpw_toolbox_h__ +#include + namespace ToolBox { void dispatch(uint16_t trap); + + + std::string ReadCString(uint32_t address); + std::string ReadPString(uint32_t address); }