mirror of
https://github.com/ksherlock/mpw.git
synced 2025-01-18 12:30:29 +00:00
HOpen (Link)
This commit is contained in:
parent
044efc7169
commit
3ad993ab3f
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
} }
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user