mirror of
https://github.com/ksherlock/mpw.git
synced 2025-01-09 13:30:34 +00:00
use OS::Internal for MPW File tables.
This commit is contained in:
parent
d59222d02f
commit
e4dff8bc81
22
mpw/mpw.cpp
22
mpw/mpw.cpp
@ -19,6 +19,7 @@
|
||||
#include <cpu/cpuModule.h>
|
||||
|
||||
#include <toolbox/mm.h>
|
||||
#include <toolbox/os_internal.h>
|
||||
|
||||
extern char **environ;
|
||||
|
||||
@ -26,7 +27,7 @@ extern char **environ;
|
||||
namespace MPW { namespace Internal {
|
||||
|
||||
// for dup counts, etc.
|
||||
std::vector<int> FDTable;
|
||||
//std::vector<int> FDTable;
|
||||
|
||||
uint32_t MacProgramInfo = 0;
|
||||
|
||||
@ -88,11 +89,30 @@ namespace MPW
|
||||
|
||||
uint16_t Init(int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
FDTable.resize(16);
|
||||
|
||||
FDTable[STDIN_FILENO] = 1;
|
||||
FDTable[STDOUT_FILENO] = 1;
|
||||
FDTable[STDERR_FILENO] = 1;
|
||||
*/
|
||||
|
||||
/*
|
||||
OS::Internal::FDTable.resize(3);
|
||||
FDTable[STDIN_FILENO].refcount = 1;
|
||||
FDTable[STDIN_FILENO].text = true;
|
||||
|
||||
FDTable[STDOUT_FILENO].refcount = 1;
|
||||
FDTable[STDOUT_FILENO].text = true;
|
||||
|
||||
FDTable[STDERR_FILENO].refcount = 1;
|
||||
FDTable[STDERR_FILENO].text = true;
|
||||
*/
|
||||
|
||||
OS::Internal::FDEntry::allocate(STDIN_FILENO).text = true;
|
||||
OS::Internal::FDEntry::allocate(STDOUT_FILENO).text = true;
|
||||
OS::Internal::FDEntry::allocate(STDERR_FILENO).text = true;
|
||||
|
||||
|
||||
std::string command = argv[0];
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <toolbox/toolbox.h>
|
||||
#include <toolbox/os.h>
|
||||
#include <toolbox/os_internal.h>
|
||||
|
||||
/*
|
||||
* access return errors are |= 0x40000000. Not entirely sure why...
|
||||
@ -30,7 +31,6 @@
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
using namespace Internal;
|
||||
|
||||
|
||||
uint32_t ftrap_open(uint32_t name, uint32_t parm)
|
||||
@ -94,11 +94,6 @@ namespace MPW
|
||||
f.error = 0;
|
||||
f.cookie = fd;
|
||||
|
||||
if (FDTable.size() <= fd)
|
||||
FDTable.resize(fd + 1);
|
||||
|
||||
FDTable[fd] = 1;
|
||||
|
||||
|
||||
// adjust the binary flags...
|
||||
// most apps are good about this but dumpobj doesn't set O_BINARY (but should)
|
||||
@ -109,6 +104,9 @@ namespace MPW
|
||||
|
||||
if (f.flags & kO_RSRC) f.flags |= kO_BINARY;
|
||||
|
||||
auto &e = OS::Internal::FDEntry::allocate(fd);
|
||||
e.text = !(f.flags & kO_BINARY);
|
||||
e.resource = f.flags & kO_RSRC;
|
||||
}
|
||||
|
||||
memoryWriteWord(f.flags, parm + 0);
|
||||
|
@ -13,11 +13,11 @@
|
||||
#include <cpu/cpuModule.h>
|
||||
|
||||
#include <toolbox/os.h>
|
||||
#include <toolbox/os_internal.h>
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
|
||||
using namespace Internal;
|
||||
|
||||
void ftrap_close(uint16_t trap)
|
||||
{
|
||||
@ -25,7 +25,7 @@ namespace MPW
|
||||
// close actually checks the error in the File Entry and converts that to unix.
|
||||
// (sigh)
|
||||
|
||||
uint32_t d0;
|
||||
uint32_t d0 = 0;
|
||||
|
||||
uint32_t sp = cpuGetAReg(7);
|
||||
uint32_t parm = memoryReadLong(sp + 4);
|
||||
@ -51,21 +51,52 @@ namespace MPW
|
||||
|
||||
int fd = f.cookie;
|
||||
|
||||
if (fd < 0 || fd >= FDTable.size() || !FDTable[fd])
|
||||
|
||||
d0 = OS::Internal::FDEntry::action(fd,
|
||||
// success callback.
|
||||
[&f](int fd, OS::Internal::FDEntry &e)
|
||||
{
|
||||
f.error = 0;
|
||||
if (--e.refcount == 0)
|
||||
{
|
||||
Log(" close(%02x)\n", fd);
|
||||
::close(fd);
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
// error callback.
|
||||
[&f](int fd){
|
||||
f.error = OS::notOpenErr;
|
||||
return kEINVAL;
|
||||
}
|
||||
);
|
||||
|
||||
#if 0
|
||||
if (fd < 0 || fd >= OS::Internal::FDTable.size())
|
||||
{
|
||||
f.error = OS::notOpenErr;
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (--FDTable[fd] == 0)
|
||||
auto &e = OS::Internal::FDTable[fd];
|
||||
if (e.refcount == 0)
|
||||
{
|
||||
Log(" close(%02x)\n", fd);
|
||||
::close(fd);
|
||||
f.error = OS::notOpenErr;
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (--e.refcount == 0)
|
||||
{
|
||||
Log(" close(%02x)\n", fd);
|
||||
::close(fd);
|
||||
}
|
||||
f.error = 0;
|
||||
d0 = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
cpuSetDReg(0, 0);
|
||||
|
@ -13,12 +13,14 @@ namespace MPW
|
||||
if (Trace) fprintf(stderr, format, args...);
|
||||
}
|
||||
|
||||
/*
|
||||
namespace Internal
|
||||
{
|
||||
// for dup counts, etc.
|
||||
extern std::vector<int> FDTable;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
#endif
|
121
mpw/mpw_io.cpp
121
mpw/mpw_io.cpp
@ -14,12 +14,12 @@
|
||||
#include <cpu/cpuModule.h>
|
||||
|
||||
#include <toolbox/os.h>
|
||||
#include <toolbox/os_internal.h>
|
||||
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
|
||||
using namespace Internal;
|
||||
|
||||
void ftrap_read(uint16_t trap)
|
||||
{
|
||||
@ -42,51 +42,27 @@ namespace MPW
|
||||
Log("%04x Read(%08x)\n", parm);
|
||||
|
||||
d0 = 0;
|
||||
int fd = f.cookie;
|
||||
ssize_t size;
|
||||
|
||||
if (f.count)
|
||||
size = OS::Internal::FDEntry::read(fd, memoryPointer(f.buffer), f.count);
|
||||
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
ssize_t size;
|
||||
|
||||
int fd = f.cookie;
|
||||
|
||||
Log(" read(%02x, %08x, %08x)\n", f.cookie, f.buffer, f.count);
|
||||
|
||||
|
||||
if (f.flags & kO_BINARY)
|
||||
{
|
||||
size = ::read(fd, memoryPointer(f.buffer), f.count);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unique_ptr<uint8_t[]> buffer(new uint8_t[f.count]);
|
||||
uint8_t *ptr = memoryPointer(f.buffer);
|
||||
|
||||
size = ::read(fd, buffer.get(), f.count);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
std::transform(buffer.get(), buffer.get() + size, ptr,
|
||||
[](uint8_t c) { return c == '\n' ? '\r' : c; }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
//f.count = 0;
|
||||
f.error = OS::ioErr; // ioErr
|
||||
d0 = errno_to_errno(errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
f.count -= size;
|
||||
f.error = 0;
|
||||
}
|
||||
|
||||
// write back...
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
memoryWriteLong(f.count, parm + 12);
|
||||
//f.count = 0;
|
||||
f.error = OS::ioErr; // ioErr
|
||||
d0 = errno_to_errno(errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
f.count -= size;
|
||||
f.error = 0;
|
||||
}
|
||||
|
||||
// write back...
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
memoryWriteLong(f.count, parm + 12);
|
||||
|
||||
cpuSetDReg(0, d0);
|
||||
}
|
||||
@ -111,48 +87,27 @@ namespace MPW
|
||||
|
||||
|
||||
d0 = 0;
|
||||
if (f.count)
|
||||
int fd = f.cookie;
|
||||
ssize_t size;
|
||||
|
||||
size = OS::Internal::FDEntry::write(fd, memoryPointer(f.buffer), f.count);
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
ssize_t size;
|
||||
|
||||
int fd = f.cookie;
|
||||
|
||||
Log(" write(%02x, %08x, %08x)\n", f.cookie, f.buffer, f.count);
|
||||
|
||||
|
||||
if (f.flags & kO_BINARY)
|
||||
{
|
||||
size = ::write(fd, memoryPointer(f.buffer), f.count);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unique_ptr<uint8_t[]> buffer(new uint8_t[f.count]);
|
||||
uint8_t *ptr = memoryPointer(f.buffer);
|
||||
|
||||
std::transform(ptr, ptr + f.count, buffer.get(),
|
||||
[](uint8_t c) { return c == '\r' ? '\n' : c; }
|
||||
);
|
||||
|
||||
size = ::write(fd, buffer.get(), f.count);
|
||||
}
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
//f.count = 0;
|
||||
f.error = -36; // ioErr
|
||||
d0 = errno_to_errno(errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is, apparently, correct.
|
||||
f.count -= size;
|
||||
f.error = 0;
|
||||
}
|
||||
|
||||
// write back...
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
memoryWriteLong(f.count, parm + 12);
|
||||
//f.count = 0;
|
||||
f.error = OS::ioErr; // ioErr
|
||||
d0 = errno_to_errno(errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
f.count -= size;
|
||||
f.error = 0;
|
||||
}
|
||||
|
||||
// write back...
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
memoryWriteLong(f.count, parm + 12);
|
||||
|
||||
cpuSetDReg(0, d0);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
@ -20,13 +21,13 @@
|
||||
#include <cpu/cpuModule.h>
|
||||
|
||||
#include <toolbox/os.h>
|
||||
#include <toolbox/os_internal.h>
|
||||
|
||||
|
||||
|
||||
|
||||
namespace MPW
|
||||
{
|
||||
using namespace Internal;
|
||||
|
||||
uint32_t ftrap_dup(uint32_t parm, uint32_t arg)
|
||||
{
|
||||
@ -46,15 +47,37 @@ namespace MPW
|
||||
|
||||
Log(" dup(%02x)\n", fd);
|
||||
|
||||
if (fd < 0 || fd >= FDTable.size() || !FDTable[fd])
|
||||
|
||||
d0 = OS::Internal::FDEntry::action(fd,
|
||||
[](int fd, OS::Internal::FDEntry &e){
|
||||
e.refcount++;
|
||||
return 0;
|
||||
},
|
||||
[](int fd){
|
||||
return kEINVAL;
|
||||
}
|
||||
);
|
||||
|
||||
#if 0
|
||||
try
|
||||
{
|
||||
auto &e = OS::Internal::FDTable.at(fd);
|
||||
|
||||
if (e.refcount)
|
||||
{
|
||||
d0 = 0;
|
||||
fd.refcount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
}
|
||||
catch(std::out_of_range &ex)
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
FDTable[fd]++;
|
||||
d0 = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
return d0;
|
||||
@ -111,21 +134,37 @@ namespace MPW
|
||||
|
||||
Log(" interactive(%02x)\n", fd);
|
||||
|
||||
//d0 = kEINVAL;
|
||||
d0 = OS::Internal::FDEntry::action(fd,
|
||||
[](int fd, OS::Internal::FDEntry &e){
|
||||
|
||||
// linkgs reads from stdin and
|
||||
// doesn't work quite right when
|
||||
// this returns 0. So, don't.
|
||||
int tty = ::isatty(fd);
|
||||
return tty ? 0 : kEINVAL;
|
||||
},
|
||||
[](int fd){
|
||||
return kEINVAL;
|
||||
}
|
||||
);
|
||||
|
||||
if (fd < 0 || fd >= FDTable.size() || !FDTable[fd])
|
||||
#if 0
|
||||
try
|
||||
{
|
||||
auto &e = OS::Internal::FDTable.at(fd);
|
||||
|
||||
if (e.refcount)
|
||||
{
|
||||
int tty = ::isatty(fd);
|
||||
d0 = tty ? 0 : kEINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
}
|
||||
catch(std::out_of_range &ex)
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
int tty = ::isatty(fd);
|
||||
d0 = tty ? 0 : kEINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
return d0;
|
||||
@ -175,6 +214,17 @@ namespace MPW
|
||||
|
||||
Log(" refnum(%02x)\n", fd);
|
||||
|
||||
d0 = OS::Internal::FDEntry::action(fd,
|
||||
[arg](int fd, OS::Internal::FDEntry &e){
|
||||
memoryWriteWord(fd, arg);
|
||||
return 0;
|
||||
},
|
||||
[](int fd){
|
||||
return kEINVAL;
|
||||
}
|
||||
);
|
||||
|
||||
#if 0
|
||||
if (fd < 0 || fd >= FDTable.size() || !FDTable[fd])
|
||||
{
|
||||
d0 = kEINVAL;
|
||||
@ -184,6 +234,7 @@ namespace MPW
|
||||
d0 = 0;
|
||||
memoryWriteWord(fd, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
memoryWriteWord(f.error, parm + 2);
|
||||
return d0;
|
||||
|
@ -1,7 +1,128 @@
|
||||
#include "os_internal.h"
|
||||
#include <stdexcept>
|
||||
#include <cerrno>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
namespace OS { namespace Internal {
|
||||
|
||||
std::deque<FDEntry> FDTable;
|
||||
//std::deque<FDEntry> FDTable;
|
||||
|
||||
std::deque<FDEntry> FDEntry::FDTable;
|
||||
FDEntry& FDEntry::allocate(int fd)
|
||||
{
|
||||
std::string noname;
|
||||
|
||||
return allocate(fd, noname);
|
||||
}
|
||||
|
||||
FDEntry& FDEntry::allocate(int fd, std::string &&filename)
|
||||
{
|
||||
if (fd < 0) throw std::out_of_range("Invalid FD");
|
||||
|
||||
if (FDTable.size() <= fd)
|
||||
FDTable.resize(fd + 1);
|
||||
|
||||
auto &e = FDTable[fd];
|
||||
e.refcount = 1;
|
||||
e.text = false;
|
||||
e.resource = false;
|
||||
e.filename = std::move(filename);
|
||||
return e;
|
||||
}
|
||||
|
||||
FDEntry& FDEntry::allocate(int fd, const std::string &filename)
|
||||
{
|
||||
if (fd < 0) throw std::out_of_range("Invalid FD");
|
||||
|
||||
if (FDTable.size() <= fd)
|
||||
FDTable.resize(fd + 1);
|
||||
|
||||
auto &e = FDTable[fd];
|
||||
e.refcount = 1;
|
||||
e.text = false;
|
||||
e.resource = false;
|
||||
e.filename = filename;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
ssize_t FDEntry::read(int fd, void *buffer, size_t count)
|
||||
{
|
||||
if (fd < 0 || fd >= FDTable.size())
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto const &e = FDTable[fd];
|
||||
if (!e.refcount)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// hmm... keep a current seek position?
|
||||
|
||||
ssize_t size;
|
||||
if (e.text)
|
||||
{
|
||||
std::unique_ptr<uint8_t[]> trbuffer(new uint8_t[count]);
|
||||
|
||||
size = ::read(fd, trbuffer.get(), count);
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
std::transform(trbuffer.get(), trbuffer.get() + size, (uint8_t *)buffer,
|
||||
[](uint8_t c) { return c == '\n' ? '\r' : c; }
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size = ::read(fd, buffer, count);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
ssize_t FDEntry::write(int fd, const void *buffer, size_t count)
|
||||
{
|
||||
if (fd < 0 || fd >= FDTable.size())
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto const &e = FDTable[fd];
|
||||
if (!e.refcount)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// hmm... keep a current seek position?
|
||||
|
||||
ssize_t size;
|
||||
if (e.text)
|
||||
{
|
||||
std::unique_ptr<uint8_t[]> trbuffer(new uint8_t[count]);
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
std::transform((const uint8_t *)buffer, (const uint8_t *)buffer + count, trbuffer.get(),
|
||||
[](uint8_t c) { return c == '\r' ? '\n' : c; }
|
||||
);
|
||||
}
|
||||
|
||||
size = ::write(fd, trbuffer.get(), count);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = ::write(fd, buffer, count);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
} }
|
||||
|
@ -13,16 +13,45 @@ namespace OS { namespace Internal {
|
||||
bool text;
|
||||
bool resource;
|
||||
|
||||
// std::string path?
|
||||
std::string filename;
|
||||
|
||||
FDEntry() :
|
||||
refcount(0),
|
||||
text(false),
|
||||
resource(false)
|
||||
{}
|
||||
|
||||
static std::deque<FDEntry> FDTable;
|
||||
|
||||
static FDEntry& allocate(int fd);
|
||||
static FDEntry& allocate(int fd, std::string &&filename);
|
||||
static FDEntry& allocate(int fd, const std::string &filename);
|
||||
|
||||
static ssize_t read(int fd, void *buffer, size_t count);
|
||||
static ssize_t write(int fd, const void *buffer, size_t count);
|
||||
|
||||
|
||||
template<class F1, class F2>
|
||||
static int32_t action(int fd, F1 good, F2 bad)
|
||||
{
|
||||
if (fd < 0 || fd >= FDTable.size())
|
||||
{
|
||||
return bad(fd);
|
||||
}
|
||||
|
||||
auto &e = FDTable[fd];
|
||||
if (e.refcount)
|
||||
{
|
||||
return good(fd, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
return bad(fd);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
extern std::deque<FDEntry> FDTable;
|
||||
|
||||
} }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user