[+] UNIX FD sharing (with Linux optimization and a potentially functional BSD fallback)
[+] IPCHandle [*] Clean up IO init
This commit is contained in:
parent
8468c4d65c
commit
37cb35d997
@ -17,4 +17,8 @@
|
||||
|
||||
#include "FS/FS.hpp"
|
||||
#include "Net/Net.hpp"
|
||||
#include "Character/Character.hpp"
|
||||
#include "Character/Character.hpp"
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
#include "UNIX/UNIX.hpp"
|
||||
#endif
|
17
Include/Aurora/IO/UNIX/UNIX.hpp
Executable file
17
Include/Aurora/IO/UNIX/UNIX.hpp
Executable file
@ -0,0 +1,17 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: UNIX.hpp
|
||||
Date: 2022-4-14
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::IO::UNIX
|
||||
{
|
||||
AUKN_SYM AuString ShareFileDescriptor(int fd);
|
||||
|
||||
AUKN_SYM void ShareFileDescriptorStop(const AuString &handle);
|
||||
|
||||
AUKN_SYM int ShareFileDescriptorAccept(const AuString &handle);
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
#include "Locale/Locale.hpp"
|
||||
#include "Console/Console.hpp"
|
||||
#include "IO/FS/FS.hpp"
|
||||
#include "IO/IO.hpp"
|
||||
#include "Hashing/Hashing.hpp"
|
||||
#include "Debug/Debug.hpp"
|
||||
#include "Async/Async.hpp"
|
||||
@ -25,10 +26,6 @@
|
||||
#if defined(AURORA_PLATFORM_WIN32)
|
||||
#include "Extensions/Win32/DarkTheme.hpp"
|
||||
#endif
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
#include "IO/UNIX/UnixIO.hpp"
|
||||
#endif
|
||||
//#include "IO/Net/Net.hpp"
|
||||
#include "Process/ProcessMap.hpp"
|
||||
#include "Exit/Exit.hpp"
|
||||
#include "CmdLine/CmdLine.hpp"
|
||||
@ -48,13 +45,10 @@ static void Init()
|
||||
Aurora::Exit::InitExit();
|
||||
Aurora::Console::Init();
|
||||
Aurora::IO::FS::InitResources();
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
Aurora::IO::UNIX::InitUnixIO();
|
||||
#endif
|
||||
Aurora::IO::Init();
|
||||
Aurora::Console::Init2();
|
||||
Aurora::HWInfo::Init();
|
||||
Aurora::Telemetry::Init();
|
||||
//Aurora::IO::Net::InitNetworking();
|
||||
Aurora::Grug::InitGrug();
|
||||
Aurora::Debug::InitDebug();
|
||||
Aurora::Locale::Init();
|
||||
@ -77,9 +71,9 @@ static void Deinit()
|
||||
Aurora::Async::ShutdownAsync();
|
||||
Aurora::Grug::DeinitGrug();
|
||||
Aurora::Console::Exit();
|
||||
//Aurora::IO::Net::DeinitNetworking();
|
||||
Aurora::Processes::Deinit();
|
||||
Aurora::Exit::DeinitExit();
|
||||
Aurora::IO::Deinit();
|
||||
}
|
||||
|
||||
namespace Aurora
|
||||
|
@ -142,6 +142,12 @@ namespace Aurora::IO::FS
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ApplyDumbAdvisoryLock(fileHandle, lock))
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
this->directIO = directIO;
|
||||
this->handle = fileHandle;
|
||||
this->readOnly = openMode == EFileOpenMode::eRead;
|
||||
|
41
Source/IO/IO.cpp
Executable file
41
Source/IO/IO.cpp
Executable file
@ -0,0 +1,41 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: IO.cpp
|
||||
Date: 2022-4-14
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "IO.hpp"
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
#include "UNIX/UnixIO.hpp"
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
#include "UNIX/IOSubmit.Linux.hpp"
|
||||
#endif
|
||||
|
||||
namespace Aurora::IO
|
||||
{
|
||||
void Init()
|
||||
{
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
UNIX::InitUnixIO();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Deinit()
|
||||
{
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
UNIX::DeinitUnixIO();
|
||||
#endif
|
||||
}
|
||||
|
||||
AUKN_SYM void SendBatched()
|
||||
{
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
UNIX::SendIOBuffers();
|
||||
#endif
|
||||
}
|
||||
}
|
14
Source/IO/IO.hpp
Executable file
14
Source/IO/IO.hpp
Executable file
@ -0,0 +1,14 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: IO.cpp
|
||||
Date: 2022-4-14
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::IO
|
||||
{
|
||||
void Init();
|
||||
void Deinit();
|
||||
}
|
461
Source/IO/UNIX/FDIpcServer.cpp
Normal file
461
Source/IO/UNIX/FDIpcServer.cpp
Normal file
@ -0,0 +1,461 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: FDIpcServer.cpp
|
||||
Date: 2022-4-12
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "UnixIO.hpp"
|
||||
#include "FDIpcServer.hpp"
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <Source/IO/FS/FS.hpp>
|
||||
#include <sys/syscall.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
|
||||
static int pidfd_getfd(int pidfd, int targetfd,
|
||||
unsigned int flags)
|
||||
{
|
||||
return syscall(SYS_pidfd_getfd, pidfd, targetfd, flags);
|
||||
}
|
||||
|
||||
static int pidfd_open(pid_t pid, unsigned int flags)
|
||||
{
|
||||
return syscall(SYS_pidfd_open, pid, flags);
|
||||
}
|
||||
|
||||
#if !defined(PIDFD_NONBLOCK)
|
||||
#define PIDFD_NONBLOCK O_NONBLOCK
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace Aurora::IO::UNIX
|
||||
{
|
||||
static AuThreadPrimitives::SpinLock gSpinLock;
|
||||
static AuThreads::ThreadUnique_t gUnixIPCHandleServeThread;
|
||||
static AuThreadPrimitives::EventUnique_t gReadyEvent;
|
||||
static AuBST<AuUInt32, int> gFdCookieMap;
|
||||
static bool gHasProcSyscall {};
|
||||
|
||||
static int WriteDescripitor(int socket, AuUInt32 cookie, int fd)
|
||||
{
|
||||
if ((fd == -1) ||
|
||||
(socket == -1))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct iovec iov
|
||||
{
|
||||
.iov_base = &cookie,
|
||||
.iov_len = sizeof(cookie)
|
||||
};
|
||||
|
||||
struct msghdr msg
|
||||
{
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
.msg_name = nullptr,
|
||||
.msg_namelen = 0
|
||||
};
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED) // smells
|
||||
|
||||
union {
|
||||
char buf[CMSG_SPACE(sizeof(fd))];
|
||||
struct cmsghdr align;
|
||||
} u;
|
||||
|
||||
msg.msg_control = u.buf;
|
||||
msg.msg_controllen = sizeof(u.buf);
|
||||
|
||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||
*cmsg = (struct cmsghdr){.cmsg_level = SOL_SOCKET,
|
||||
.cmsg_type = SCM_RIGHTS,
|
||||
.cmsg_len = CMSG_LEN(sizeof(fd))};
|
||||
|
||||
AuWriteU32(CMSG_DATA(cmsg), 0, fd);
|
||||
#else // lain hue
|
||||
msg.msg_accrights = (caddr_t) &fd;
|
||||
msg.msg_accrightslen = sizeof(fd);
|
||||
#endif
|
||||
|
||||
return ::sendmsg(socket, &msg, 0);
|
||||
}
|
||||
|
||||
static int ReadDescriptor(int socket, AuUInt32 cookie)
|
||||
{
|
||||
AuUInt32 foreignCookie {};
|
||||
int newFd {-1};
|
||||
int ret {};
|
||||
|
||||
if (socket == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct iovec iov
|
||||
{
|
||||
.iov_base = &foreignCookie,
|
||||
.iov_len = sizeof(foreignCookie)
|
||||
};
|
||||
|
||||
struct msghdr msg
|
||||
{
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1,
|
||||
.msg_name = nullptr,
|
||||
.msg_namelen = 0
|
||||
};
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
union {
|
||||
char buf[CMSG_SPACE(sizeof(newFd))];
|
||||
struct cmsghdr align;
|
||||
} u;
|
||||
|
||||
msg.msg_control = u.buf;
|
||||
msg.msg_controllen = sizeof(u.buf);
|
||||
#else
|
||||
msg.msg_accrights = (caddr_t) &newFd;
|
||||
msg.msg_accrightslen = sizeof(newFd);
|
||||
#endif
|
||||
|
||||
if ((ret = ::recvmsg(socket, &msg, 0)) <= 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
auto cmptr = CMSG_FIRSTHDR(&msg);
|
||||
if (!cmptr)
|
||||
{
|
||||
SysPushErrorIO();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cmptr->cmsg_len != CMSG_LEN(sizeof(int)))
|
||||
{
|
||||
SysPushErrorIO("IPC FD Packet interrupted");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cmptr->cmsg_level != SOL_SOCKET)
|
||||
{
|
||||
SysPushErrorIO("cmsg_level expected SOL_SOCKET");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cmptr->cmsg_type != SCM_RIGHTS)
|
||||
{
|
||||
SysPushErrorIO("cmsg_type expected SCM_RIGHTS");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return AuReadU32(CMSG_DATA(cmptr), 0);
|
||||
|
||||
#else
|
||||
|
||||
if (msg.msg_accrightslen != sizeof(int))
|
||||
{
|
||||
SysPushErrorIO("IPC FD Packet interrupted");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return newFd;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool WriteDescripitorRequest(int socket, AuUInt32 cookie)
|
||||
{
|
||||
return ::write(socket, &cookie, sizeof(cookie)) == sizeof(cookie);
|
||||
}
|
||||
|
||||
static bool ReadDescripitorRequest(int socket, AuUInt32 &cookie)
|
||||
{
|
||||
timeval tv {};
|
||||
tv.tv_usec = 5000;
|
||||
::setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, AuReinterpretCast<const char *>(&tv), sizeof(tv));
|
||||
return ::read(socket, &cookie, sizeof(cookie)) == sizeof(cookie);
|
||||
}
|
||||
|
||||
static AuString GetServerPath(pid_t pid)
|
||||
{
|
||||
AuString path;
|
||||
|
||||
#if 0
|
||||
if (!AuIOFS::GetUserProgramsFolder(path))
|
||||
{
|
||||
path = "/opt/";
|
||||
}
|
||||
#endif
|
||||
path += "/tmp/UNIX_IPC/";
|
||||
path += AuToString(AuUInt32(pid));
|
||||
return path;
|
||||
}
|
||||
|
||||
static bool GetServerName(sockaddr_un &sockAddr, pid_t pid)
|
||||
{
|
||||
auto path = GetServerPath(pid);
|
||||
if (path.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AuTryResize(path, AuArraySize(sockAddr.sun_path) - 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
sockAddr.sun_family = AF_UNIX;
|
||||
AuMemcpy(sockAddr.sun_path, path.c_str(), path.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ServerThread()
|
||||
{
|
||||
sockaddr_un addr {};
|
||||
|
||||
int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd <= 0)
|
||||
{
|
||||
SysPanic("Couldn't spawn IPC socket");
|
||||
}
|
||||
|
||||
if (!GetServerName(addr, getpid()))
|
||||
{
|
||||
::close(fd);
|
||||
SysPanic("Get IPC socket server name");
|
||||
}
|
||||
|
||||
AuIOFS::CreateDirectories(addr.sun_path, true);
|
||||
|
||||
if (::bind(fd, AuReinterpretCast<struct sockaddr *>(&addr), sizeof(addr)) == -1)
|
||||
{
|
||||
SysPanic("Couldn't bind IPC socket {}", errno);
|
||||
}
|
||||
|
||||
if (::listen(fd, 128) == -1)
|
||||
{
|
||||
SysPanic("Couldn't listen to IPC socket {}", errno);
|
||||
}
|
||||
|
||||
gReadyEvent->Set();
|
||||
|
||||
while (AuIsThreadRunning())
|
||||
{
|
||||
AuUInt32 cookie;
|
||||
|
||||
int client = ::accept(fd, NULL, NULL);
|
||||
if (client == -1)
|
||||
{
|
||||
SysPushErrorIO("IPC accept error {}", errno);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ReadDescripitorRequest(client, cookie))
|
||||
{
|
||||
SysPushErrorIO("IPC request timed out {}", errno);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
{
|
||||
AU_LOCK_GUARD(gSpinLock);
|
||||
|
||||
auto itr = gFdCookieMap.find(cookie);
|
||||
if (itr == gFdCookieMap.end())
|
||||
{
|
||||
SysPushErrorIO("Missing IPC cookie: {}", cookie);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (!WriteDescripitor(client, cookie, itr->second))
|
||||
{
|
||||
SysPushErrorIO("Couldn't write IPC packet");
|
||||
goto cont;
|
||||
}
|
||||
}
|
||||
|
||||
cont:
|
||||
::close(client);
|
||||
}
|
||||
|
||||
::close(fd);
|
||||
}
|
||||
|
||||
static bool ReadyServer()
|
||||
{
|
||||
if (gUnixIPCHandleServeThread)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
gReadyEvent = AuThreadPrimitives::EventUnique(false, false, true);
|
||||
if (!gReadyEvent)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
gUnixIPCHandleServeThread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
|
||||
AuMakeShared<AuThreads::IThreadVectorsFunctional>(AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind(ServerThread)),
|
||||
AuThreads::IThreadVectorsFunctional::OnExit_t{}),
|
||||
"UNIX IPC File Descriptor Server"
|
||||
));
|
||||
|
||||
if (!gUnixIPCHandleServeThread)
|
||||
{
|
||||
gReadyEvent.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gUnixIPCHandleServeThread->Run())
|
||||
{
|
||||
return bool(gUnixIPCHandleServeThread = {});
|
||||
}
|
||||
|
||||
gReadyEvent->Lock();
|
||||
gReadyEvent.reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Ready()
|
||||
{
|
||||
AU_LOCK_GUARD(gSpinLock);
|
||||
|
||||
if (gHasProcSyscall)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return ReadyServer();
|
||||
}
|
||||
|
||||
bool FDServe(bool a, bool b, bool c, bool d, int fd, IPC::IPCHandle &outHandle)
|
||||
{
|
||||
if (gHasProcSyscall)
|
||||
{
|
||||
outHandle.NewId(a, b, c, d);
|
||||
outHandle.cookie = fd;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Ready())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
AU_LOCK_GUARD(gSpinLock);
|
||||
|
||||
do
|
||||
{
|
||||
outHandle.NewId(a, b, c, d);
|
||||
} while (AuExists(gFdCookieMap, outHandle.cookie));
|
||||
|
||||
return AuTryInsert(gFdCookieMap, outHandle.cookie, fd);
|
||||
}
|
||||
}
|
||||
|
||||
void FDServeEnd(const IPC::IPCHandle &handle)
|
||||
{
|
||||
if (gHasProcSyscall)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AU_LOCK_GUARD(gSpinLock);
|
||||
AuTryRemove(gFdCookieMap, handle.cookie);
|
||||
}
|
||||
|
||||
bool FDAccept(const IPC::IPCHandle &handle, int &outFd)
|
||||
{
|
||||
sockaddr_un addr;
|
||||
outFd = -1;
|
||||
|
||||
if (gHasProcSyscall)
|
||||
{
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
|
||||
int pid = ::pidfd_open(handle.ToUnixPid(), 0);
|
||||
if (pid <= 0)
|
||||
{
|
||||
SysPushErrorIO("Couldn't open IPC server pid, error: {}", pid);
|
||||
return false;
|
||||
}
|
||||
|
||||
int result = ::pidfd_getfd(pid, handle.cookie, 0);
|
||||
if (result <= 0)
|
||||
{
|
||||
SysPushErrorIO("Couldn't get IPC fd, error: {} {}", result, errno);
|
||||
::close(pid);
|
||||
return false;
|
||||
}
|
||||
|
||||
::close(pid);
|
||||
outFd = result;
|
||||
return true;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
int fd = ::socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd <= -1)
|
||||
{
|
||||
SysPushErrorIO("No Resource?");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetServerName(addr, handle.ToUnixPid()))
|
||||
{
|
||||
::close(fd);
|
||||
SysPushErrorIO("Couldn't get remote IPC socket server name");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::connect(fd, AuReinterpretCast<struct sockaddr *>(&addr), sizeof(addr)) == -1)
|
||||
{
|
||||
::close(fd);
|
||||
SysPushErrorIO("Couldn't connect to remote IPC fd server");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WriteDescripitorRequest(fd, handle.cookie))
|
||||
{
|
||||
SysPushErrorIO("Couldn't write FD request to IPC server");
|
||||
return false;
|
||||
}
|
||||
|
||||
outFd = ReadDescriptor(fd, handle.cookie);
|
||||
if (outFd == -1)
|
||||
{
|
||||
SysPushErrorNested();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InitIPCBackend()
|
||||
{
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
auto &platform = AuSwInfo::GetPlatformInfo();
|
||||
|
||||
if ((platform.uKernelMajor > 5) ||
|
||||
((platform.uKernelMajor == 5) && (platform.uKernelMinor >= 6)))
|
||||
{
|
||||
gHasProcSyscall = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void DeinitIPCBackend()
|
||||
{
|
||||
gUnixIPCHandleServeThread.reset();
|
||||
gFdCookieMap.clear();
|
||||
gReadyEvent.reset();
|
||||
}
|
||||
}
|
21
Source/IO/UNIX/FDIpcServer.hpp
Normal file
21
Source/IO/UNIX/FDIpcServer.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: FDIpcServer.hpp
|
||||
Date: 2022-4-12
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#include <Source/IPC/IPCHandle.hpp>
|
||||
|
||||
namespace Aurora::IO::UNIX
|
||||
{
|
||||
void InitIPCBackend();
|
||||
void DeinitIPCBackend();
|
||||
|
||||
bool FDServe(bool a, bool b, bool c, bool d, int fd, IPC::IPCHandle &outHandle);
|
||||
void FDServeEnd(const IPC::IPCHandle &handle);
|
||||
|
||||
bool FDAccept(const IPC::IPCHandle &handle, int &outFd);
|
||||
}
|
@ -7,27 +7,60 @@
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "UnixIO.hpp"
|
||||
#include "FDIpcServer.hpp"
|
||||
|
||||
namespace Aurora::IO::UNIX
|
||||
{
|
||||
void InitUnixIO()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
#include "IOSubmit.Linux.hpp"
|
||||
#endif
|
||||
|
||||
namespace Aurora::IO
|
||||
{
|
||||
AUKN_SYM void SendBatched()
|
||||
AUKN_SYM AuString ShareFileDescriptor(int fd)
|
||||
{
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
UNIX::SendIOBuffers();
|
||||
#endif
|
||||
IPC::IPCHandle handle;
|
||||
|
||||
if (!FDServe(false, false, false, false, fd, handle))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return handle.ToString();
|
||||
}
|
||||
|
||||
AUKN_SYM void ShareFileDescriptorStop(const AuString &handle)
|
||||
{
|
||||
IPC::IPCHandle handle2;
|
||||
if (!handle2.FromString(handle))
|
||||
{
|
||||
SysPushErrorIO("Invalid handle string");
|
||||
return;
|
||||
}
|
||||
|
||||
FDServeEnd(handle2);
|
||||
}
|
||||
|
||||
AUKN_SYM int ShareFileDescriptorAccept(const AuString &handle)
|
||||
{
|
||||
IPC::IPCHandle handle2;
|
||||
if (!handle2.FromString(handle))
|
||||
{
|
||||
SysPushErrorIO("Invalid handle string");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fd {-1};
|
||||
if (!FDAccept(handle2, fd))
|
||||
{
|
||||
SysPushErrorNested();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
void InitUnixIO()
|
||||
{
|
||||
InitIPCBackend();
|
||||
}
|
||||
|
||||
void DeinitUnixIO()
|
||||
{
|
||||
DeinitIPCBackend();
|
||||
}
|
||||
}
|
@ -10,4 +10,5 @@
|
||||
namespace Aurora::IO::UNIX
|
||||
{
|
||||
void InitUnixIO();
|
||||
void DeinitUnixIO();
|
||||
}
|
14
Source/IPC/IPC.cpp
Executable file
14
Source/IPC/IPC.cpp
Executable file
@ -0,0 +1,14 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: IPC.cpp
|
||||
Date: 2022-4-13
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "IPC.hpp"
|
||||
|
||||
namespace Aurora::IPC
|
||||
{
|
||||
|
||||
}
|
13
Source/IPC/IPC.hpp
Executable file
13
Source/IPC/IPC.hpp
Executable file
@ -0,0 +1,13 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: IPC.hpp
|
||||
Date: 2022-4-13
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::IPC
|
||||
{
|
||||
|
||||
}
|
149
Source/IPC/IPCHandle.cpp
Executable file
149
Source/IPC/IPCHandle.cpp
Executable file
@ -0,0 +1,149 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: IPCHandle.cpp
|
||||
Date: 2022-4-13
|
||||
Author: Reece
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "IPC.hpp"
|
||||
#include "IPCHandle.hpp"
|
||||
|
||||
namespace Aurora::IPC
|
||||
{
|
||||
#define AURORA_IPC_BRAND "AuroraIPC_"
|
||||
|
||||
// A horribly inefficient parsable handle.
|
||||
// Dead simple to implement, it's 22:07, and i wanna sleep soon.
|
||||
// We should text serialize a bitmap later...
|
||||
|
||||
void IPCHandle::NewId(bool a, bool b, bool c, bool d)
|
||||
{
|
||||
this->flags[0] = a;
|
||||
this->flags[1] = b;
|
||||
this->flags[2] = c;
|
||||
this->flags[3] = d;
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
this->cookie = AuRng::RngU32();
|
||||
this->pid = getpid();
|
||||
#else
|
||||
auto temp = AuRng::ReadString(AuArraySize(this->path), AuRng::ERngStringCharacters::eAlphaNumericCharacters);
|
||||
AuMemcpy(this->path, temp.data(), data.size());
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IPCHandle::FromString(const AuString &in)
|
||||
{
|
||||
if (in.size() < 4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this->flags[0] = in[0] == 'Y';
|
||||
this->flags[1] = in[1] == 'Y';
|
||||
this->flags[2] = in[2] == 'Y';
|
||||
this->flags[3] = in[3] == 'Y';
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
if (in.size() != 4 + 16)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AuMemcpy(path, &in[4], 16);
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
|
||||
char *endPtr;
|
||||
auto word = strtoll(in.c_str() + 4, &endPtr, 10);
|
||||
if (errno == ERANGE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*endPtr != '_')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this->cookie = word;
|
||||
|
||||
word = strtoll(endPtr + 1, &endPtr, 10);
|
||||
if (errno == ERANGE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*endPtr != '\00')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this->pid = word;
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
AuString IPCHandle::ToString() const
|
||||
{
|
||||
AuString ret;
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
if (!AuTryResize(ret, 4 + 16))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
if (!AuTryResize(ret, 4))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
ret[0] = this->flags[0] ? 'Y' : 'N';
|
||||
ret[1] = this->flags[1] ? 'Y' : 'N';
|
||||
ret[2] = this->flags[2] ? 'Y' : 'N';
|
||||
ret[3] = this->flags[3] ? 'Y' : 'N';
|
||||
|
||||
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
AuMemcpy(&ret[4], this->path, 16);
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
ret += AuToString(this->cookie);
|
||||
ret += '_';
|
||||
ret += AuToString(this->pid);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AuString IPCHandle::ToNTPath() const
|
||||
{
|
||||
if (this->flags[3])
|
||||
{
|
||||
return "Global\\" AURORA_IPC_BRAND + AuString(this->path, this->path + 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Local\\" AURORA_IPC_BRAND + AuString(this->path, this->path + 16);
|
||||
}
|
||||
}
|
||||
|
||||
AuUInt32 IPCHandle::ToUnixServerCookie() const
|
||||
{
|
||||
return this->cookie;
|
||||
}
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
pid_t IPCHandle::ToUnixPid() const
|
||||
{
|
||||
return this->pid;
|
||||
}
|
||||
#endif
|
||||
}
|
36
Source/IPC/IPCHandle.hpp
Executable file
36
Source/IPC/IPCHandle.hpp
Executable file
@ -0,0 +1,36 @@
|
||||
/***
|
||||
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: IPCHandle.hpp
|
||||
Date: 2022-4-13
|
||||
Author: Reece
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
namespace Aurora::IPC
|
||||
{
|
||||
struct IPCHandle
|
||||
{
|
||||
bool flags[4];
|
||||
|
||||
union
|
||||
{
|
||||
char path[16];
|
||||
struct
|
||||
{
|
||||
AuUInt32 cookie;
|
||||
AuUInt32 pid;
|
||||
};
|
||||
};
|
||||
|
||||
void NewId(bool a, bool b, bool c, bool d);
|
||||
bool FromString(const AuString &in);
|
||||
AuString ToString() const;
|
||||
AuString ToNTPath() const;
|
||||
AuUInt32 ToUnixServerCookie() const;
|
||||
|
||||
#if defined(AURORA_IS_POSIX_DERIVED)
|
||||
pid_t ToUnixPid() const;
|
||||
#endif
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user