From 3ad993ab3f9f21a1c14a819e94657369ab141ba9 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sat, 18 May 2013 21:24:49 -0400 Subject: [PATCH] HOpen (Link) --- toolbox/os.h | 1 + toolbox/os_highlevel.cpp | 43 +++++++++++++++++++++ toolbox/os_internal.cpp | 82 +++++++++++++++++++++++++++++++++------- toolbox/os_internal.h | 2 + toolbox/toolbox.cpp | 4 ++ 5 files changed, 118 insertions(+), 14 deletions(-) diff --git a/toolbox/os.h b/toolbox/os.h index 3c56350..243e29f 100644 --- a/toolbox/os.h +++ b/toolbox/os.h @@ -53,6 +53,7 @@ namespace OS uint16_t HGetVol(uint16_t trap); uint16_t Open(uint16_t trap); + uint16_t HOpen(uint16_t trap); uint16_t Read(uint16_t trap); uint16_t Write(uint16_t trap); diff --git a/toolbox/os_highlevel.cpp b/toolbox/os_highlevel.cpp index 16ffbce..bc2cebf 100644 --- a/toolbox/os_highlevel.cpp +++ b/toolbox/os_highlevel.cpp @@ -391,5 +391,48 @@ namespace OS { } + uint16_t HOpen(uint16_t trap) + { + + int fd; + int d0; + + + uint32_t parm = cpuGetAReg(0); + + Log("%04x HOpen(%08x)\n", trap, parm); + + uint32_t ioNamePtr = memoryReadLong(parm + 18); + uint8_t ioPermission = memoryReadByte(parm + 27); + uint32_t ioDirID = memoryReadLong(parm + 48); + + std::string sname = ToolBox::ReadPString(ioNamePtr, true); + bool absolute = sname.length() ? sname[0] == '/' : 0; + + if (ioDirID && !absolute) + { + std::string dir = FSSpecManager::pathForID(ioDirID); + if (dir.empty()) + { + d0 = MacOS::dirNFErr; + memoryWriteWord(d0, parm + 16); + + return d0; + } + sname = dir + sname; + } + + fd = Internal::FDEntry::open(sname, ioPermission, false); + + d0 = fd < 0 ? fd : 0; + if (fd >= 0) + { + memoryWriteWord(fd, parm + 24); + } + + memoryWriteWord(d0, parm + 16); + return d0; + } + } \ No newline at end of file diff --git a/toolbox/os_internal.cpp b/toolbox/os_internal.cpp index bf452bd..a6cbf05 100644 --- a/toolbox/os_internal.cpp +++ b/toolbox/os_internal.cpp @@ -2,44 +2,48 @@ #include "os.h" #include "toolbox.h" +#include + #include #include #include #include #include +#include #include +using ToolBox::Log; + namespace OS { namespace Internal { uint16_t errno_to_oserr(int xerrno) { - using namespace ToolBox::Errors; switch (xerrno) { case 0: return 0; - 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 EBADF: return MacOS::rfNumErr; + case EIO: return MacOS::ioErr; + case EACCES: return MacOS::permErr; + case ENOENT: return MacOS::fnfErr; + case ENOTDIR: return MacOS::dirNFErr; + case EISDIR: return MacOS::notAFileErr; + case ENOTSUP: return MacOS::extFSErr; + case EROFS: return MacOS::wPrErr; - case EEXIST: return dupFNErr; + case EEXIST: return MacOS::dupFNErr; - case EBUSY: return fBsyErr; + case EBUSY: return MacOS::fBsyErr; - case EDQUOT: return dskFulErr; - case ENOSPC: return dskFulErr; + case EDQUOT: return MacOS::dskFulErr; + case ENOSPC: return MacOS::dskFulErr; default: - return ioErr; + return MacOS::ioErr; } } @@ -433,4 +437,54 @@ namespace OS { namespace Internal { } + int FDEntry::open(const std::string &filename, int ioPermission, int fork) + { + int fd; + + if (filename.empty()) return MacOS::bdNamErr; + + int access = 0; + switch(ioPermission) + { + case fsWrPerm: + case fsRdWrPerm: + case fsRdWrShPerm: + case fsCurPerm: + access = O_RDWR; + break; + case fsRdPerm: + access = O_RDONLY; + break; + default: + return MacOS::paramErr; + break; + } + + std::string xname = filename; + if (fork) + xname.append(_PATH_RSRCFORKSPEC); + + Log(" open(%s, %04x)\n", xname.c_str(), access); + + fd = ::open(xname.c_str(), access); + if (fd < 0 && ioPermission == fsCurPerm && errno == EACCES) + { + fd = ::open(xname.c_str(), O_RDONLY); + } + + if (fd < 0) + { + return errno_to_oserr(errno); + } + + // allocate the fd entry + + auto &e = OS::Internal::FDEntry::allocate(fd, filename); + e.resource = fork; + e.text = fork ? false : IsTextFile(filename); + + return fd; + } + + } } diff --git a/toolbox/os_internal.h b/toolbox/os_internal.h index 6c97f88..e30ed93 100644 --- a/toolbox/os_internal.h +++ b/toolbox/os_internal.h @@ -40,6 +40,8 @@ namespace OS { namespace Internal { static int close(int fd, bool force = false); + static int open(const std::string &filename, int permission, int fork); + template static int32_t action(int fd, F1 good, F2 bad) diff --git a/toolbox/toolbox.cpp b/toolbox/toolbox.cpp index 7fd6293..21c0f67 100644 --- a/toolbox/toolbox.cpp +++ b/toolbox/toolbox.cpp @@ -35,6 +35,10 @@ namespace ToolBox { d0 = OS::Open(trap); break; + case 0xa200: + d0 = OS::HOpen(trap); + break; + case 0xa001: d0 = OS::Close(trap); break;