HOpen (Link)

This commit is contained in:
Kelvin Sherlock 2013-05-18 21:24:49 -04:00
parent 044efc7169
commit 3ad993ab3f
5 changed files with 118 additions and 14 deletions

View File

@ -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);

View File

@ -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;
}
}

View File

@ -2,44 +2,48 @@
#include "os.h"
#include "toolbox.h"
#include <macos/errors.h>
#include <stdexcept>
#include <cerrno>
#include <unistd.h>
#include <fcntl.h>
#include <sys/xattr.h>
#include <sys/paths.h>
#include <machine/endian.h>
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;
}
} }

View File

@ -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<class F1, class F2>
static int32_t action(int fd, F1 good, F2 bad)

View File

@ -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;