mirror of
https://github.com/ksherlock/mpw.git
synced 2024-06-08 02:29:36 +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 <cpu/cpuModule.h>
|
||||||
|
|
||||||
#include <toolbox/mm.h>
|
#include <toolbox/mm.h>
|
||||||
|
#include <toolbox/os_internal.h>
|
||||||
|
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ extern char **environ;
|
||||||
namespace MPW { namespace Internal {
|
namespace MPW { namespace Internal {
|
||||||
|
|
||||||
// for dup counts, etc.
|
// for dup counts, etc.
|
||||||
std::vector<int> FDTable;
|
//std::vector<int> FDTable;
|
||||||
|
|
||||||
uint32_t MacProgramInfo = 0;
|
uint32_t MacProgramInfo = 0;
|
||||||
|
|
||||||
|
@ -88,11 +89,30 @@ namespace MPW
|
||||||
|
|
||||||
uint16_t Init(int argc, char **argv)
|
uint16_t Init(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
FDTable.resize(16);
|
FDTable.resize(16);
|
||||||
|
|
||||||
FDTable[STDIN_FILENO] = 1;
|
FDTable[STDIN_FILENO] = 1;
|
||||||
FDTable[STDOUT_FILENO] = 1;
|
FDTable[STDOUT_FILENO] = 1;
|
||||||
FDTable[STDERR_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];
|
std::string command = argv[0];
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <toolbox/toolbox.h>
|
#include <toolbox/toolbox.h>
|
||||||
#include <toolbox/os.h>
|
#include <toolbox/os.h>
|
||||||
|
#include <toolbox/os_internal.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* access return errors are |= 0x40000000. Not entirely sure why...
|
* access return errors are |= 0x40000000. Not entirely sure why...
|
||||||
|
@ -30,7 +31,6 @@
|
||||||
|
|
||||||
namespace MPW
|
namespace MPW
|
||||||
{
|
{
|
||||||
using namespace Internal;
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ftrap_open(uint32_t name, uint32_t parm)
|
uint32_t ftrap_open(uint32_t name, uint32_t parm)
|
||||||
|
@ -94,11 +94,6 @@ namespace MPW
|
||||||
f.error = 0;
|
f.error = 0;
|
||||||
f.cookie = fd;
|
f.cookie = fd;
|
||||||
|
|
||||||
if (FDTable.size() <= fd)
|
|
||||||
FDTable.resize(fd + 1);
|
|
||||||
|
|
||||||
FDTable[fd] = 1;
|
|
||||||
|
|
||||||
|
|
||||||
// adjust the binary flags...
|
// adjust the binary flags...
|
||||||
// most apps are good about this but dumpobj doesn't set O_BINARY (but should)
|
// 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;
|
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);
|
memoryWriteWord(f.flags, parm + 0);
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
#include <cpu/cpuModule.h>
|
#include <cpu/cpuModule.h>
|
||||||
|
|
||||||
#include <toolbox/os.h>
|
#include <toolbox/os.h>
|
||||||
|
#include <toolbox/os_internal.h>
|
||||||
|
|
||||||
namespace MPW
|
namespace MPW
|
||||||
{
|
{
|
||||||
|
|
||||||
using namespace Internal;
|
|
||||||
|
|
||||||
void ftrap_close(uint16_t trap)
|
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.
|
// close actually checks the error in the File Entry and converts that to unix.
|
||||||
// (sigh)
|
// (sigh)
|
||||||
|
|
||||||
uint32_t d0;
|
uint32_t d0 = 0;
|
||||||
|
|
||||||
uint32_t sp = cpuGetAReg(7);
|
uint32_t sp = cpuGetAReg(7);
|
||||||
uint32_t parm = memoryReadLong(sp + 4);
|
uint32_t parm = memoryReadLong(sp + 4);
|
||||||
|
@ -51,21 +51,52 @@ namespace MPW
|
||||||
|
|
||||||
int fd = f.cookie;
|
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;
|
f.error = OS::notOpenErr;
|
||||||
d0 = kEINVAL;
|
d0 = kEINVAL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (--FDTable[fd] == 0)
|
auto &e = OS::Internal::FDTable[fd];
|
||||||
|
if (e.refcount == 0)
|
||||||
{
|
{
|
||||||
Log(" close(%02x)\n", fd);
|
f.error = OS::notOpenErr;
|
||||||
::close(fd);
|
d0 = kEINVAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (--e.refcount == 0)
|
||||||
|
{
|
||||||
|
Log(" close(%02x)\n", fd);
|
||||||
|
::close(fd);
|
||||||
|
}
|
||||||
f.error = 0;
|
f.error = 0;
|
||||||
d0 = 0;
|
d0 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
memoryWriteWord(f.error, parm + 2);
|
memoryWriteWord(f.error, parm + 2);
|
||||||
cpuSetDReg(0, 0);
|
cpuSetDReg(0, 0);
|
||||||
|
|
|
@ -13,12 +13,14 @@ namespace MPW
|
||||||
if (Trace) fprintf(stderr, format, args...);
|
if (Trace) fprintf(stderr, format, args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
namespace Internal
|
namespace Internal
|
||||||
{
|
{
|
||||||
// for dup counts, etc.
|
// for dup counts, etc.
|
||||||
extern std::vector<int> FDTable;
|
extern std::vector<int> FDTable;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
121
mpw/mpw_io.cpp
121
mpw/mpw_io.cpp
|
@ -14,12 +14,12 @@
|
||||||
#include <cpu/cpuModule.h>
|
#include <cpu/cpuModule.h>
|
||||||
|
|
||||||
#include <toolbox/os.h>
|
#include <toolbox/os.h>
|
||||||
|
#include <toolbox/os_internal.h>
|
||||||
|
|
||||||
|
|
||||||
namespace MPW
|
namespace MPW
|
||||||
{
|
{
|
||||||
|
|
||||||
using namespace Internal;
|
|
||||||
|
|
||||||
void ftrap_read(uint16_t trap)
|
void ftrap_read(uint16_t trap)
|
||||||
{
|
{
|
||||||
|
@ -42,51 +42,27 @@ namespace MPW
|
||||||
Log("%04x Read(%08x)\n", parm);
|
Log("%04x Read(%08x)\n", parm);
|
||||||
|
|
||||||
d0 = 0;
|
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;
|
//f.count = 0;
|
||||||
|
f.error = OS::ioErr; // ioErr
|
||||||
int fd = f.cookie;
|
d0 = errno_to_errno(errno);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f.count -= size;
|
||||||
|
f.error = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write back...
|
||||||
|
memoryWriteWord(f.error, parm + 2);
|
||||||
|
memoryWriteLong(f.count, parm + 12);
|
||||||
|
|
||||||
cpuSetDReg(0, d0);
|
cpuSetDReg(0, d0);
|
||||||
}
|
}
|
||||||
|
@ -111,48 +87,27 @@ namespace MPW
|
||||||
|
|
||||||
|
|
||||||
d0 = 0;
|
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;
|
//f.count = 0;
|
||||||
|
f.error = OS::ioErr; // ioErr
|
||||||
int fd = f.cookie;
|
d0 = errno_to_errno(errno);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f.count -= size;
|
||||||
|
f.error = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write back...
|
||||||
|
memoryWriteWord(f.error, parm + 2);
|
||||||
|
memoryWriteLong(f.count, parm + 12);
|
||||||
|
|
||||||
cpuSetDReg(0, d0);
|
cpuSetDReg(0, d0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -20,13 +21,13 @@
|
||||||
#include <cpu/cpuModule.h>
|
#include <cpu/cpuModule.h>
|
||||||
|
|
||||||
#include <toolbox/os.h>
|
#include <toolbox/os.h>
|
||||||
|
#include <toolbox/os_internal.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace MPW
|
namespace MPW
|
||||||
{
|
{
|
||||||
using namespace Internal;
|
|
||||||
|
|
||||||
uint32_t ftrap_dup(uint32_t parm, uint32_t arg)
|
uint32_t ftrap_dup(uint32_t parm, uint32_t arg)
|
||||||
{
|
{
|
||||||
|
@ -46,15 +47,37 @@ namespace MPW
|
||||||
|
|
||||||
Log(" dup(%02x)\n", fd);
|
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;
|
d0 = kEINVAL;
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
{
|
|
||||||
FDTable[fd]++;
|
|
||||||
d0 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memoryWriteWord(f.error, parm + 2);
|
memoryWriteWord(f.error, parm + 2);
|
||||||
return d0;
|
return d0;
|
||||||
|
@ -111,21 +134,37 @@ namespace MPW
|
||||||
|
|
||||||
Log(" interactive(%02x)\n", fd);
|
Log(" interactive(%02x)\n", fd);
|
||||||
|
|
||||||
//d0 = kEINVAL;
|
d0 = OS::Internal::FDEntry::action(fd,
|
||||||
|
[](int fd, OS::Internal::FDEntry &e){
|
||||||
|
|
||||||
// linkgs reads from stdin and
|
int tty = ::isatty(fd);
|
||||||
// doesn't work quite right when
|
return tty ? 0 : kEINVAL;
|
||||||
// this returns 0. So, don't.
|
},
|
||||||
|
[](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;
|
d0 = kEINVAL;
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
{
|
|
||||||
int tty = ::isatty(fd);
|
|
||||||
d0 = tty ? 0 : kEINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memoryWriteWord(f.error, parm + 2);
|
memoryWriteWord(f.error, parm + 2);
|
||||||
return d0;
|
return d0;
|
||||||
|
@ -175,6 +214,17 @@ namespace MPW
|
||||||
|
|
||||||
Log(" refnum(%02x)\n", fd);
|
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])
|
if (fd < 0 || fd >= FDTable.size() || !FDTable[fd])
|
||||||
{
|
{
|
||||||
d0 = kEINVAL;
|
d0 = kEINVAL;
|
||||||
|
@ -184,6 +234,7 @@ namespace MPW
|
||||||
d0 = 0;
|
d0 = 0;
|
||||||
memoryWriteWord(fd, arg);
|
memoryWriteWord(fd, arg);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
memoryWriteWord(f.error, parm + 2);
|
memoryWriteWord(f.error, parm + 2);
|
||||||
return d0;
|
return d0;
|
||||||
|
|
|
@ -1,7 +1,128 @@
|
||||||
#include "os_internal.h"
|
#include "os_internal.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
namespace OS { namespace Internal {
|
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 text;
|
||||||
bool resource;
|
bool resource;
|
||||||
|
|
||||||
// std::string path?
|
std::string filename;
|
||||||
|
|
||||||
FDEntry() :
|
FDEntry() :
|
||||||
refcount(0),
|
refcount(0),
|
||||||
text(false),
|
text(false),
|
||||||
resource(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…
Reference in New Issue
Block a user