mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 07:00:43 +02:00
FEXServer: Adds -w option for waiting on current FEXServer
It can be useful to know in tooling when the current active FEXServer has exited. Two things can happen when this command is run. No FEXServer is active, returns immediately. A FEXServer is active, we query for a pidfd from the active server, then we wait until it exits. Both instances of this is valid to use.
This commit is contained in:
1 parent
04a1ac967c
commit
e03d253310
6 files changed
+195
-107
No files matched your search
@@ -215,6 +215,72 @@ namespace ProcessPipe {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SendEmptyErrorPacket(int Socket) {
|
||||
FEXServerClient::FEXServerResultPacket Res {
|
||||
.Header {
|
||||
.Type = FEXServerClient::PacketType::TYPE_ERROR,
|
||||
},
|
||||
};
|
||||
|
||||
struct iovec iov {
|
||||
.iov_base = &Res,
|
||||
.iov_len = sizeof(Res),
|
||||
};
|
||||
|
||||
struct msghdr msg {
|
||||
.msg_name = nullptr,
|
||||
.msg_namelen = 0,
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
sendmsg(Socket, &msg, 0);
|
||||
}
|
||||
|
||||
void SendFDSuccessPacket(int Socket, int FD) {
|
||||
FEXServerClient::FEXServerResultPacket Res {
|
||||
.Header {
|
||||
.Type = FEXServerClient::PacketType::TYPE_SUCCESS,
|
||||
},
|
||||
};
|
||||
|
||||
struct iovec iov {
|
||||
.iov_base = &Res,
|
||||
.iov_len = sizeof(Res),
|
||||
};
|
||||
|
||||
struct msghdr msg {
|
||||
.msg_name = nullptr,
|
||||
.msg_namelen = 0,
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
// Setup the ancillary buffer. This is where we will be getting pipe FDs
|
||||
// We only need 4 bytes for the FD
|
||||
constexpr size_t CMSG_SIZE = CMSG_SPACE(sizeof(int));
|
||||
union AncillaryBuffer {
|
||||
struct cmsghdr Header;
|
||||
uint8_t Buffer[CMSG_SIZE];
|
||||
};
|
||||
AncillaryBuffer AncBuf{};
|
||||
|
||||
// Now link to our ancilllary buffer
|
||||
msg.msg_control = AncBuf.Buffer;
|
||||
msg.msg_controllen = CMSG_SIZE;
|
||||
|
||||
// Now we need to setup the ancillary buffer data. We are only sending an FD
|
||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
|
||||
// We are giving the daemon the write side of the pipe
|
||||
memcpy(CMSG_DATA(cmsg), &FD, sizeof(int));
|
||||
|
||||
sendmsg(Socket, &msg, 0);
|
||||
}
|
||||
|
||||
void HandleSocketData(int Socket) {
|
||||
std::vector<uint8_t> Data(1500);
|
||||
size_t CurrentRead{};
|
||||
@@ -266,54 +332,14 @@ namespace ProcessPipe {
|
||||
CurrentOffset += sizeof(FEXServerClient::FEXServerRequestPacket::BasicRequest);
|
||||
break;
|
||||
case FEXServerClient::PacketType::TYPE_GET_LOG_FD: {
|
||||
FEXServerClient::FEXServerResultPacket Res {
|
||||
.Header {
|
||||
.Type = FEXServerClient::PacketType::TYPE_SUCCESS,
|
||||
},
|
||||
};
|
||||
|
||||
struct iovec iov {
|
||||
.iov_base = &Res,
|
||||
.iov_len = sizeof(Res),
|
||||
};
|
||||
|
||||
struct msghdr msg {
|
||||
.msg_name = nullptr,
|
||||
.msg_namelen = 0,
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
};
|
||||
|
||||
if (Logger::LogThreadRunning()) {
|
||||
// Setup the ancillary buffer. This is where we will be getting pipe FDs
|
||||
// We only need 4 bytes for the FD
|
||||
constexpr size_t CMSG_SIZE = CMSG_SPACE(sizeof(int));
|
||||
union AncillaryBuffer {
|
||||
struct cmsghdr Header;
|
||||
uint8_t Buffer[CMSG_SIZE];
|
||||
};
|
||||
AncillaryBuffer AncBuf{};
|
||||
|
||||
// Now link to our ancilllary buffer
|
||||
msg.msg_control = AncBuf.Buffer;
|
||||
msg.msg_controllen = CMSG_SIZE;
|
||||
|
||||
// Now we need to setup the ancillary buffer data. We are only sending an FD
|
||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
|
||||
int fds[2]{};
|
||||
pipe2(fds, 0);
|
||||
// 0 = Read
|
||||
// 1 = Write
|
||||
Logger::AppendLogFD(fds[0]);
|
||||
|
||||
// We are giving the daemon the write side of the pipe
|
||||
memcpy(CMSG_DATA(cmsg), &fds[1], sizeof(int));
|
||||
|
||||
sendmsg(Socket, &msg, 0);
|
||||
SendFDSuccessPacket(Socket, fds[1]);
|
||||
|
||||
// Close the write side now, doesn't matter to us
|
||||
close(fds[1]);
|
||||
@@ -324,14 +350,12 @@ namespace ProcessPipe {
|
||||
}
|
||||
else {
|
||||
// Log thread isn't running. Let FEXInterpreter know it can't have one.
|
||||
Res.Header.Type = FEXServerClient::PacketType::TYPE_ERROR;
|
||||
|
||||
sendmsg(Socket, &msg, 0);
|
||||
SendEmptyErrorPacket(Socket);
|
||||
}
|
||||
|
||||
CurrentOffset += sizeof(FEXServerClient::FEXServerRequestPacket::Header);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case FEXServerClient::PacketType::TYPE_GET_ROOTFS_PATH: {
|
||||
std::string MountFolder = SquashFS::GetMountFolder();
|
||||
|
||||
@@ -372,6 +396,17 @@ namespace ProcessPipe {
|
||||
|
||||
CurrentOffset += sizeof(FEXServerClient::FEXServerRequestPacket::BasicRequest);
|
||||
break;
|
||||
}
|
||||
case FEXServerClient::PacketType::TYPE_GET_PID_FD: {
|
||||
int FD = ::syscall(SYS_pidfd_open, ::getpid(), 0);
|
||||
|
||||
SendFDSuccessPacket(Socket, FD);
|
||||
|
||||
// Close the FD now since we've sent it
|
||||
close(FD);
|
||||
|
||||
CurrentOffset += sizeof(FEXServerClient::FEXServerRequestPacket::Header);
|
||||
break;
|
||||
}
|
||||
// Invalid
|
||||
case FEXServerClient::PacketType::TYPE_ERROR:
|
||||
|
||||
Reference in new issue
Block a user