mkxp-sunshine/src/pipe.h
2026-07-14 12:43:43 -04:00

137 lines
2.1 KiB
C++

#ifndef PIPE_H
#define PIPE_H
#ifdef _WIN32
#include <windows.h>
#else
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif
class Pipe{
public:
typedef enum {
Write,
Read,
} Mode;
Pipe(){
#ifdef _WIN32
handle = NULL;
#else
fd = 0;
#endif
}
Pipe(const char *name_, Mode mode_){
open(name_, mode_);
}
~Pipe(){
#ifndef _WIN32
if (mode == Write)
unlink(filename.c_str());
#endif
}
void open(const char *name_, Mode mode_){
name = name_;
mode = mode_;
#ifdef _WIN32
filename = std::string("\\\\.\\pipe\\") + name;
#else
filename = std::string(P_tmpdir) + "/" + name;
#endif
if (mode == Read){
#ifdef _WIN32
handle = CreateFileA(
filename.c_str(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
#else
fd = ::open(filename.c_str(), O_RDONLY | O_NONBLOCK);
#endif
} else {
#ifdef _WIN32
handle = CreateNamedPipeA(
filename.c_str(),
PIPE_ACCESS_OUTBOUND,
PIPE_TYPE_BYTE,
PIPE_UNLIMITED_INSTANCES,
256, 0, 0, NULL);
#else
mkfifo(filename.c_str(), 0666);
fd = 0;
#endif
}
}
void connect(){
#ifdef _WIN32
ConnectNamedPipe(handle, NULL);
#else
fd = ::open(filename.c_str(), O_WRONLY);
#endif
}
void close(){
#ifdef _WIN32
CloseHandle(handle);
handle = NULL;
#else
::close(fd);
fd = 0;
#endif
}
bool read(char *buf)
{
#ifdef _WIN32
OVERLAPPED overlapped;
SDL_memset(&overlapped, 0, sizeof(overlapped));
if (!ReadFile(handle, buf, 1, NULL, &overlapped)){
if (GetLastError() == ERROR_IO_PENDING)
CancelIo(handle);
return false;
}
return true;
#else
return ::read(fd, buf, 1) == 1;
#endif
}
void write(const char *buf, size_t size){
#ifdef _WIN32
WriteFile(handle, buf, size, NULL, NULL);
#else
::write(fd, buf, size);
#endif
}
bool isOpen(){
#ifdef _WIN32
return handle != NULL;
#else
return fd != 0;
#endif
}
private:
std::string name;
std::string filename;
Mode mode;
#ifdef _WIN32
HANDLE handle;
#else
int fd;
#endif
};
#endif // PIPE_H