Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepy-monax committed Dec 22, 2023
1 parent 9e0064d commit 74ad134
Show file tree
Hide file tree
Showing 24 changed files with 612 additions and 282 deletions.
3 changes: 2 additions & 1 deletion src/impls/impl-efi/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"provides": [
"karm-logger-impl",
"karm-sys-impl",
"karm-ui-impl"
"karm-ui-impl",
"karm-async-impl"
]
}
34 changes: 17 additions & 17 deletions src/impls/impl-efi/sys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace Karm::Sys::_Embed {

struct ConOut : public Sys::Fd {
struct ConOut : public Sys::Handle {
Efi::SimpleTextOutputProtocol *_proto;

ConOut(Efi::SimpleTextOutputProtocol *proto) : _proto(proto) {}
Expand Down Expand Up @@ -54,11 +54,11 @@ struct ConOut : public Sys::Fd {
return Ok(0uz);
}

Res<Strong<Fd>> dup() override {
Res<Strong<Handle>> dup() override {
notImplemented();
}

Res<Cons<Strong<Fd>, SocketAddr>> accept() override {
Res<Cons<Strong<Handle>, SocketAddr>> accept() override {
notImplemented();
}

Expand All @@ -67,7 +67,7 @@ struct ConOut : public Sys::Fd {
}
};

struct FileProto : public Sys::Fd {
struct FileProto : public Sys::Handle {
Efi::FileProtocol *_proto = nullptr;

FileProto(Efi::FileProtocol *proto) : _proto(proto) {}
Expand Down Expand Up @@ -129,11 +129,11 @@ struct FileProto : public Sys::Fd {
return Ok(0uz);
}

Res<Strong<Fd>> dup() override {
Res<Strong<Handle>> dup() override {
notImplemented();
}

Res<Cons<Strong<Fd>, SocketAddr>> accept() override {
Res<Cons<Strong<Handle>, SocketAddr>> accept() override {
notImplemented();
}

Expand All @@ -153,25 +153,25 @@ struct FileProto : public Sys::Fd {
}
};

Res<Strong<Sys::Fd>> createIn() {
return Ok(makeStrong<Sys::DummyFd>());
Res<Strong<Sys::Handle>> createIn() {
return Ok(makeStrong<Sys::NullHandle>());
}

Res<Strong<Sys::Fd>> createOut() {
Res<Strong<Sys::Handle>> createOut() {
return Ok(makeStrong<ConOut>(Efi::st()->conOut));
}

Res<Strong<Sys::Fd>> createErr() {
Res<Strong<Sys::Handle>> createErr() {
return Ok(makeStrong<ConOut>(Efi::st()->stdErr));
}

/* --- Sockets -------------------------------------------------------------- */

Res<Strong<Sys::Fd>> connectTcp(SocketAddr) {
Res<Strong<Sys::Handle>> connectTcp(SocketAddr) {
notImplemented();
}

Res<Strong<Sys::Fd>> listenTcp(SocketAddr) {
Res<Strong<Sys::Handle>> listenTcp(SocketAddr) {
notImplemented();
}

Expand Down Expand Up @@ -234,7 +234,7 @@ static Res<Url::Path> resolve(Url::Url url) {
}
}

Res<Strong<Sys::Fd>> openFile(Url::Url url) {
Res<Strong<Sys::Handle>> openFile(Url::Url url) {
static Efi::SimpleFileSystemProtocol *fileSystem = nullptr;
if (not fileSystem) {
fileSystem = try$(Efi::openProtocol<Efi::SimpleFileSystemProtocol>(Efi::li()->deviceHandle));
Expand Down Expand Up @@ -264,7 +264,7 @@ Res<Vec<Sys::DirEntry>> readDir(Url::Url) {
return Error::notImplemented();
}

Res<Strong<Sys::Fd>> createFile(Url::Url) {
Res<Strong<Sys::Handle>> createFile(Url::Url) {
return Error::notImplemented();
}

Expand All @@ -281,9 +281,9 @@ Res<Sys::MmapResult> memMap(Karm::Sys::MmapOptions const &options) {
return Ok(Sys::MmapResult{vaddr, vaddr, options.size});
}

Res<Sys::MmapResult> memMap(Karm::Sys::MmapOptions const &, Strong<Sys::Fd> fd) {
Res<Sys::MmapResult> memMap(Karm::Sys::MmapOptions const &, Strong<Sys::Handle> hdn) {
usize vaddr = 0;
usize fileSize = try$(Io::size(*fd));
usize fileSize = try$(Io::size(*hdn));

try$(Efi::bs()->allocatePages(
Efi::AllocateType::ANY_PAGES,
Expand All @@ -292,7 +292,7 @@ Res<Sys::MmapResult> memMap(Karm::Sys::MmapOptions const &, Strong<Sys::Fd> fd)

MutBytes bytes = {(Byte *)vaddr, fileSize};
Io::BufWriter writer{bytes};
try$(Io::copy(*fd, writer));
try$(Io::copy(*hdn, writer));

// Memory is identity mapped, so we can just return the virtual address as paddr
return Ok(Sys::MmapResult{vaddr, vaddr, Hal::pageAlignUp(fileSize)});
Expand Down
156 changes: 113 additions & 43 deletions src/impls/impl-posix/sys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ static SocketAddr fromSockAddr(struct sockaddr_in sockaddr) {

/* --- File Descriptor ------------------------------------------------------ */

struct PosixFd : public Sys::Fd {
struct PosixHandle : public Sys::Handle {
isize _raw;

PosixFd(isize raw) : _raw(raw) {}
PosixHandle(isize raw) : _raw(raw) {}

Res<usize> read(MutBytes bytes) override {
isize result = ::read(_raw, bytes.buf(), sizeOf(bytes));
Expand Down Expand Up @@ -91,24 +91,24 @@ struct PosixFd : public Sys::Fd {
return Ok(0uz);
}

Res<Strong<Fd>> dup() override {
Res<Strong<Handle>> dup() override {
isize duped = ::dup(_raw);

if (duped < 0)
return Posix::fromLastErrno();

return Ok(makeStrong<PosixFd>(duped));
return Ok(makeStrong<PosixHandle>(duped));
}

Res<Cons<Strong<Fd>, SocketAddr>> accept() override {
Res<Cons<Strong<Handle>, SocketAddr>> accept() override {
struct sockaddr_in addr_;
socklen_t len = sizeof(addr_);
isize fd = ::accept(_raw, (struct sockaddr *)&addr_, &len);
if (fd < 0)
isize hdn = ::accept(_raw, (struct sockaddr *)&addr_, &len);
if (hdn < 0)
return Posix::fromLastErrno();

return Ok<Cons<Strong<Fd>, SocketAddr>>(
makeStrong<PosixFd>(fd),
return Ok<Cons<Strong<Handle>, SocketAddr>>(
makeStrong<PosixHandle>(hdn),
fromSockAddr(addr_));
}

Expand All @@ -121,6 +121,76 @@ struct PosixFd : public Sys::Fd {
.size = (usize)buf.st_size,
});
}

Res<> sendHandle(Strong<Handle> hdn) override {
auto *posixHandle = hdn.is<PosixHandle>();
if (not posixHandle)
return Error::invalidHandle("hdn is not a posix hdn");

struct iovec iov {};
// We need to send at least one byte of data
char data{};
iov.iov_base = &data;
iov.iov_len = sizeof(data);

struct msghdr msg {};
msg.msg_name = nullptr;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_controllen = CMSG_SPACE(sizeof(int));
Array<Byte, CMSG_SPACE(sizeof(int))> ctrl_buf{};
msg.msg_control = ctrl_buf.buf();

struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));

*((int *)CMSG_DATA(cmsg)) = posixHandle->_raw;

if (::sendmsg(_raw, &msg, 0) < 0)
return Posix::fromLastErrno();

return Ok();
}

Res<Strong<Handle>> recvHandle() override {
struct iovec iov {};
// We need to send at least one byte of data
char data{};
iov.iov_base = &data;
iov.iov_len = sizeof(data);

struct msghdr msg {};
msg.msg_name = nullptr;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_controllen = CMSG_SPACE(sizeof(int));
Array<Byte, CMSG_SPACE(sizeof(int))> ctrl_buf{};
msg.msg_control = ctrl_buf.buf();

if (::recvmsg(_raw, &msg, 0) < 0)
return Posix::fromLastErrno();

struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
if (not cmsg)
return Error::invalidHandle("no cmsg");

if (cmsg->cmsg_level != SOL_SOCKET)
return Error::invalidHandle("invalid cmsg level");

if (cmsg->cmsg_type != SCM_RIGHTS)
return Error::invalidHandle("invalid cmsg type");

if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
return Error::invalidHandle("invalid cmsg len");

int hdn = *((int *)CMSG_DATA(cmsg));

return Ok(makeStrong<PosixHandle>(hdn));
}
};

Res<Url::Path> resolve(Url::Url url) {
Expand Down Expand Up @@ -150,14 +220,14 @@ Res<Url::Path> resolve(Url::Url url) {
return Ok(resolved);
}

Res<Strong<Sys::Fd>> openFile(Url::Url url) {
Res<Strong<Sys::Handle>> openFile(Url::Url url) {
String str = try$(resolve(url)).str();
isize fd = ::open(str.buf(), O_RDONLY);
isize hdn = ::open(str.buf(), O_RDONLY);

if (fd < 0)
if (hdn < 0)
return Posix::fromLastErrno();

return Ok(makeStrong<PosixFd>(fd));
return Ok(makeStrong<PosixHandle>(hdn));
}

Res<Vec<Sys::DirEntry>> readDir(Url::Url url) {
Expand Down Expand Up @@ -188,74 +258,74 @@ Res<Vec<Sys::DirEntry>> readDir(Url::Url url) {
return Ok(entries);
}

Res<Strong<Sys::Fd>> createFile(Url::Url url) {
Res<Strong<Sys::Handle>> createFile(Url::Url url) {
String str = try$(resolve(url)).str();

auto fd = ::open(str.buf(), O_RDWR | O_CREAT, 0644);
auto hdn = ::open(str.buf(), O_RDWR | O_CREAT, 0644);

if (fd < 0) {
if (hdn < 0) {
return Posix::fromLastErrno();
}

return Ok(makeStrong<PosixFd>(fd));
return Ok(makeStrong<PosixHandle>(hdn));
}

Res<Pair<Strong<Sys::Fd>>> createPipe() {
Res<Pair<Strong<Sys::Handle>>> createPipe() {
int fds[2];

if (::pipe(fds) < 0)
return Posix::fromLastErrno();

return Ok(Pair<Strong<Sys::Fd>>{
makeStrong<PosixFd>(fds[0]),
makeStrong<PosixFd>(fds[1]),
return Ok(Pair<Strong<Sys::Handle>>{
makeStrong<PosixHandle>(fds[0]),
makeStrong<PosixHandle>(fds[1]),
});
}

Res<Strong<Sys::Fd>> createIn() {
return Ok(makeStrong<PosixFd>(0));
Res<Strong<Sys::Handle>> createIn() {
return Ok(makeStrong<PosixHandle>(0));
}

Res<Strong<Sys::Fd>> createOut() {
return Ok(makeStrong<PosixFd>(1));
Res<Strong<Sys::Handle>> createOut() {
return Ok(makeStrong<PosixHandle>(1));
}

Res<Strong<Sys::Fd>> createErr() {
return Ok(makeStrong<PosixFd>(2));
Res<Strong<Sys::Handle>> createErr() {
return Ok(makeStrong<PosixHandle>(2));
}

/* --- Sockets -------------------------------------------------------------- */

Res<Strong<Sys::Fd>> connectTcp(SocketAddr addr) {
int fd = ::socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
Res<Strong<Sys::Handle>> connectTcp(SocketAddr addr) {
int hdn = ::socket(AF_INET, SOCK_STREAM, 0);
if (hdn < 0)
return Posix::fromLastErrno();

struct sockaddr_in addr_ = toSockAddr(addr);
if (::connect(fd, (struct sockaddr *)&addr_, sizeof(addr_)) < 0)
if (::connect(hdn, (struct sockaddr *)&addr_, sizeof(addr_)) < 0)
return Posix::fromLastErrno();

return Ok(makeStrong<PosixFd>(fd));
return Ok(makeStrong<PosixHandle>(hdn));
}

Res<Strong<Sys::Fd>> listenTcp(SocketAddr addr) {
int fd = ::socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
Res<Strong<Sys::Handle>> listenTcp(SocketAddr addr) {
int hdn = ::socket(AF_INET, SOCK_STREAM, 0);
if (hdn < 0)
return Posix::fromLastErrno();

int opt = 1;
if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
if (::setsockopt(hdn, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
return Posix::fromLastErrno();

struct sockaddr_in addr_ = toSockAddr(addr);

if (::bind(fd, (struct sockaddr *)&addr_, sizeof(addr_)) < 0)
if (::bind(hdn, (struct sockaddr *)&addr_, sizeof(addr_)) < 0)
return Posix::fromLastErrno();

if (::listen(fd, 128) < 0)
if (::listen(hdn, 128) < 0)
return Posix::fromLastErrno();

return Ok(makeStrong<PosixFd>(fd));
return Ok(makeStrong<PosixHandle>(hdn));
}

/* --- Time ----------------------------------------------------------------- */
Expand Down Expand Up @@ -308,14 +378,14 @@ Res<Sys::MmapResult> memMap(Karm::Sys::MmapOptions const &options) {
return Ok(Sys::MmapResult{0, (usize)addr, (usize)options.size});
}

Res<Sys::MmapResult> memMap(Sys::MmapOptions const &options, Strong<Sys::Fd> maybeFd) {
Strong<PosixFd> fd = try$(maybeFd.cast<PosixFd>());
Res<Sys::MmapResult> memMap(Sys::MmapOptions const &options, Strong<Sys::Handle> maybeHandle) {
Strong<PosixHandle> hdn = try$(maybeHandle.cast<PosixHandle>());
usize size = options.size;

if (size == 0)
size = try$(Io::size(*fd));
size = try$(Io::size(*hdn));

void *addr = mmap((void *)options.vaddr, size, mmapOptionsToProt(options), MAP_SHARED, fd->_raw, options.offset);
void *addr = mmap((void *)options.vaddr, size, mmapOptionsToProt(options), MAP_SHARED, hdn->_raw, options.offset);

if (addr == MAP_FAILED)
return Posix::fromLastErrno();
Expand Down
Loading

0 comments on commit 74ad134

Please sign in to comment.