use OS::Internal for MPW File tables.

This commit is contained in:
Kelvin Sherlock 2013-02-25 20:16:55 -05:00
parent d59222d02f
commit e4dff8bc81
8 changed files with 324 additions and 117 deletions

View File

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

View File

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

View File

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

View File

@ -13,12 +13,14 @@ namespace MPW
if (Trace) fprintf(stderr, format, args...);
}
/*
namespace Internal
{
// for dup counts, etc.
extern std::vector<int> FDTable;
}
*/
}
#endif

View File

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

View File

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

View File

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

View File

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