FEX/Source/Tools/FEXServer/PipeScanner.cpp
Ryan Houdek 5fe6afc270 FEXServer: Adds new FEXServer service
This is a relatively invasive change since multiple things needed to
happen at once.

* Socket based logging is removed
  * Logging has been replaced to only support stdout, stderr, and server
  * Server is now default and replaces what FEXLogServer did
  * Server logging now uses a pipe instead of a socket
  * Can be faster than stderr and stdout since the application doesn't
    need to wait on terminal output

* FEXMountDaemon has been removed
  * Functionality has been merged in to FEXServer

* FEXServer is always executed on FEX initialization time
  * Similar in behaviour to Wine's wineserver
  * Can explicitly start this before using FEX for logging purposes
  * Stays around until all instances of FEX exit
  * Will stick around for a short amount of time in case of spurious
    execution

* FEXServer will soon be extended to do more than logging and squashfs
  mounting

* FEX rootfs scripts will need to be updated to support this path
  * Just means rbinding the /tmp folder and forcing a FEXServer instance
    to be alive
* Pressure-vessel works fine in this case since FEXServer will already
  be running
  * It already rbinds the host /tmp folder which is why this works
2022-06-23 07:51:56 -07:00

50 lines
1.2 KiB
C++

#include <cstdlib>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <vector>
namespace PipeScanner {
std::vector<int> IncomingPipes{};
// Scan and store any pipe files.
// This will capture all pipe files so needs to be executed early.
// This ensures we find any pipe files from execve for waiting FEXInterpreters.
void ScanForPipes() {
DIR *fd = opendir("/proc/self/fd");
if (fd) {
struct dirent *dir{};
do {
dir = readdir(fd);
if (dir) {
char *end{};
int open_fd = std::strtol(dir->d_name, &end, 8);
if (end != dir->d_name) {
struct stat stat{};
int result = fstat(open_fd, &stat);
if (result == -1) {
continue;
}
if (stat.st_mode & S_IFIFO) {
// Close any incoming pipes
IncomingPipes.emplace_back(open_fd);
}
}
}
} while (dir);
closedir(fd);
}
}
void ClosePipes() {
for (auto pipe : IncomingPipes) {
int Null{0};
write(pipe, &Null, sizeof(Null));
close(pipe);
}
IncomingPipes.clear();
}
}