diff --git a/libc/generic/linux/src/sys-epoll.cpp b/libc/generic/linux/src/sys-epoll.cpp index dc7e5bdc..fa6386d1 100644 --- a/libc/generic/linux/src/sys-epoll.cpp +++ b/libc/generic/linux/src/sys-epoll.cpp @@ -8,21 +8,6 @@ int epoll_create(int) { __builtin_unreachable(); } -int epoll_create1(int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int epoll_ctl(int, int, int, struct epoll_event *) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - -int epoll_wait(int, struct epoll_event *, int, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); -} - int epoll_pwait(int, struct epoll_event *, int, int, const sigset_t *) { __ensure(!"Not implemented"); __builtin_unreachable(); diff --git a/libc/platform/x86_64-managarm/src/file.cpp b/libc/platform/x86_64-managarm/src/file.cpp index 4e42a5d4..7039a27d 100644 --- a/libc/platform/x86_64-managarm/src/file.cpp +++ b/libc/platform/x86_64-managarm/src/file.cpp @@ -767,6 +767,131 @@ int socketpair(int domain, int type, int proto, int *fds) { return 0; } +#include + +int epoll_create1(int flags) { + __ensure(!flags); + + HelAction actions[3]; + globalQueue.trim(); + + managarm::posix::CntRequest req(getAllocator()); + req.set_request_type(managarm::posix::CntReqType::EPOLL_CREATE); + + frigg::String ser(getAllocator()); + req.SerializeToString(&ser); + actions[0].type = kHelActionOffer; + actions[0].flags = kHelItemAncillary; + actions[1].type = kHelActionSendFromBuffer; + actions[1].flags = kHelItemChain; + actions[1].buffer = ser.data(); + actions[1].length = ser.size(); + actions[2].type = kHelActionRecvInline; + actions[2].flags = 0; + HEL_CHECK(helSubmitAsync(kHelThisThread, actions, 3, + globalQueue.getQueue(), 0, 0)); + + auto element = globalQueue.dequeueSingle(); + auto offer = parseSimple(element); + auto send_req = parseSimple(element); + auto recv_resp = parseInline(element); + + HEL_CHECK(offer->error); + HEL_CHECK(send_req->error); + HEL_CHECK(recv_resp->error); + + managarm::posix::SvrResponse resp(getAllocator()); + resp.ParseFromArray(recv_resp->data, recv_resp->length); + __ensure(resp.error() == managarm::posix::Errors::SUCCESS); + return resp.fd(); +} + +int epoll_ctl(int epfd, int mode, int fd, struct epoll_event *ev) { + __ensure(mode == EPOLL_CTL_ADD); + + HelAction actions[3]; + globalQueue.trim(); + + managarm::posix::CntRequest req(getAllocator()); + req.set_request_type(managarm::posix::CntReqType::EPOLL_CTL); + req.set_fd(epfd); + req.set_newfd(fd); + req.set_flags(ev->events); + req.set_cookie(ev->data.u64); + + frigg::String ser(getAllocator()); + req.SerializeToString(&ser); + actions[0].type = kHelActionOffer; + actions[0].flags = kHelItemAncillary; + actions[1].type = kHelActionSendFromBuffer; + actions[1].flags = kHelItemChain; + actions[1].buffer = ser.data(); + actions[1].length = ser.size(); + actions[2].type = kHelActionRecvInline; + actions[2].flags = 0; + HEL_CHECK(helSubmitAsync(kHelThisThread, actions, 3, + globalQueue.getQueue(), 0, 0)); + + auto element = globalQueue.dequeueSingle(); + auto offer = parseSimple(element); + auto send_req = parseSimple(element); + auto recv_resp = parseInline(element); + + HEL_CHECK(offer->error); + HEL_CHECK(send_req->error); + HEL_CHECK(recv_resp->error); + + managarm::posix::SvrResponse resp(getAllocator()); + resp.ParseFromArray(recv_resp->data, recv_resp->length); + __ensure(resp.error() == managarm::posix::Errors::SUCCESS); + return 0; +} + +int epoll_wait(int epfd, struct epoll_event *evnts, int n, int timeout) { + __ensure(timeout == -1); + + HelAction actions[4]; + globalQueue.trim(); + + managarm::posix::CntRequest req(getAllocator()); + req.set_request_type(managarm::posix::CntReqType::EPOLL_WAIT); + req.set_fd(epfd); + + frigg::String ser(getAllocator()); + req.SerializeToString(&ser); + actions[0].type = kHelActionOffer; + actions[0].flags = kHelItemAncillary; + actions[1].type = kHelActionSendFromBuffer; + actions[1].flags = kHelItemChain; + actions[1].buffer = ser.data(); + actions[1].length = ser.size(); + actions[2].type = kHelActionRecvInline; + actions[2].flags = kHelItemChain; + actions[3].type = kHelActionRecvToBuffer; + actions[3].flags = 0; + actions[3].buffer = evnts; + actions[3].length = n * sizeof(struct epoll_event); + HEL_CHECK(helSubmitAsync(kHelThisThread, actions, 4, + globalQueue.getQueue(), 0, 0)); + + auto element = globalQueue.dequeueSingle(); + auto offer = parseSimple(element); + auto send_req = parseSimple(element); + auto recv_resp = parseInline(element); + auto recv_data = parseLength(element); + + HEL_CHECK(offer->error); + HEL_CHECK(send_req->error); + HEL_CHECK(recv_resp->error); + HEL_CHECK(recv_data->error); + + managarm::posix::SvrResponse resp(getAllocator()); + resp.ParseFromArray(recv_resp->data, recv_resp->length); + __ensure(resp.error() == managarm::posix::Errors::SUCCESS); + __ensure(!(recv_data->length % sizeof(struct epoll_event))); + return recv_data->length / sizeof(struct epoll_event); +} + #include #include @@ -1402,6 +1527,7 @@ int ioctl(int fd, unsigned long request, void *arg) { assert(!(param->flags & ~DRM_MODE_PAGE_FLIP_EVENT)); req.set_drm_crtc_id(param->crtc_id); req.set_drm_fb_id(param->fb_id); + req.set_drm_cookie(param->user_data); frigg::String ser(getAllocator()); req.SerializeToString(&ser);