[*] Harden IPC pipes
This commit is contained in:
parent
a932aa57d2
commit
9b99e6e7c7
@ -336,7 +336,7 @@ namespace Aurora::IO::FS
|
||||
return false;
|
||||
}
|
||||
|
||||
if (written != blockSize)
|
||||
if (!written)
|
||||
{
|
||||
SysPushErrorNested("File Error: {}", path_);
|
||||
break;
|
||||
|
@ -93,20 +93,37 @@ namespace Aurora::IO::IPC
|
||||
if (serverHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
this->hasClient_ = Loop::NewLSEvent(false, false, true);
|
||||
SysAssert(this->hasClient_);
|
||||
if (!this->hasClient_)
|
||||
{
|
||||
this->bDead = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->fsHandle_ = AuIO::IOHandleShared();
|
||||
SysAssert(this->fsHandle_);
|
||||
if (!this->fsHandle_)
|
||||
{
|
||||
this->bDead = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this->fsStream_ = AuMakeSharedPanic<IO::FS::NtAsyncFileStream>();
|
||||
this->fsStream_ = AuMakeShared<IO::FS::NtAsyncFileStream>();
|
||||
if (!this->fsStream_)
|
||||
{
|
||||
this->bDead = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this->fsHandle_->InitFromMove((AuUInt)this->GetPipeHandle());
|
||||
(void)this->fsHandle_->InitFromMove((AuUInt)this->GetPipeHandle());
|
||||
AuStaticCast<AFileHandle>(this->fsHandle_)->bIsAsync = true;
|
||||
AuStaticCast<AFileHandle>(this->fsHandle_)->pIPCPipe = this;
|
||||
|
||||
this->fsBlockingStream_ = AuFS::OpenBlockingFileStreamFromHandle(this->fsHandle_);
|
||||
SysAssert(this->fsBlockingStream_);
|
||||
if (!this->fsBlockingStream_)
|
||||
{
|
||||
this->bDead = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this->fsStream_->Init(this->fsHandle_);
|
||||
|
||||
@ -392,6 +409,13 @@ namespace Aurora::IO::IPC
|
||||
return {};
|
||||
}
|
||||
|
||||
if (object->bDead)
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
SysPushErrorNested();
|
||||
return {};
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
@ -442,11 +466,18 @@ namespace Aurora::IO::IPC
|
||||
auto object = AuMakeShared<IPCPipeImpl>(pipe, INVALID_HANDLE_VALUE, handle);
|
||||
if (!object)
|
||||
{
|
||||
SysPushErrorMem();
|
||||
SysPushErrorMemory();
|
||||
AuWin32CloseHandle(pipe);
|
||||
return {};
|
||||
}
|
||||
|
||||
if (object->bDead)
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
SysPushErrorNested();
|
||||
return {};
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ namespace Aurora::IO::IPC
|
||||
OVERLAPPED overlapped {};
|
||||
HANDLE clientHandle_ {INVALID_HANDLE_VALUE};
|
||||
|
||||
bool bDead {};
|
||||
AuSPtr<Loop::ILSEvent> hasClient_;
|
||||
private:
|
||||
HANDLE serverHandle_ {INVALID_HANDLE_VALUE};
|
||||
|
@ -15,8 +15,15 @@
|
||||
#include <termios.h>
|
||||
#include <Source/IO/AuIOHandle.hpp>
|
||||
|
||||
namespace Aurora::IO::FS
|
||||
{
|
||||
bool PosixWrite(int fd, const void *buf, AuUInt32 count, AuUInt32 *pWritten);
|
||||
}
|
||||
|
||||
namespace Aurora::IO::IPC
|
||||
{
|
||||
static const AuUInt64 kFileCopyBlock = 0x4000; // 16KiB
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Pipes
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -162,19 +169,31 @@ namespace Aurora::IO::IPC
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
this->fsHandle_ = AuIO::IOHandleShared();
|
||||
SysAssert(this->fsHandle_);
|
||||
if (!this->fsHandle_)
|
||||
{
|
||||
this->bDead = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this->fsStream_ = AuMakeShared<IO::FS::LinuxAsyncFileStream>();
|
||||
if (!this->fsStream_)
|
||||
{
|
||||
this->bDead = true;
|
||||
return;
|
||||
}
|
||||
|
||||
AuStaticCast<AFileHandle>(this->fsHandle_)->pIPCPipe = this;
|
||||
|
||||
this->fsHandle_->InitFromPairMove(fds2[0], fds2[1]);
|
||||
(void)this->fsHandle_->InitFromPairMove(fds2[0], fds2[1]);
|
||||
this->fsStream_->Init(this->fsHandle_);
|
||||
|
||||
this->fsBlockingStream_ = AuFS::OpenBlockingFileStreamFromHandle(this->fsHandle_);
|
||||
SysAssert(this->fsBlockingStream_);
|
||||
if (!this->fsBlockingStream_)
|
||||
{
|
||||
this->bDead = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AuSPtr<Loop::ILoopSource> IPCPipeImpl::AsReadChannelIsOpen()
|
||||
@ -287,23 +306,33 @@ namespace Aurora::IO::IPC
|
||||
{
|
||||
::fcntl(handle, F_SETFL, control);
|
||||
}
|
||||
|
||||
int tmp;
|
||||
do
|
||||
|
||||
AuUInt length = read.length;
|
||||
AuUInt offset {0};
|
||||
|
||||
while (length)
|
||||
{
|
||||
tmp = ::write(handle, read.ptr, read.length);
|
||||
}
|
||||
while ((tmp == -1 && errno == EINTR));
|
||||
AuUInt32 written;
|
||||
|
||||
if (tmp <= 0)
|
||||
{
|
||||
if (tmp == 0)
|
||||
int blockSize = AuMin(AuUInt(kFileCopyBlock), length);
|
||||
|
||||
if (!FS::PosixWrite(handle, &reinterpret_cast<const char *>(read.ptr)[offset], blockSize, &written))
|
||||
{
|
||||
if (!nonblock)
|
||||
{
|
||||
SysPushErrorNested("File Error: {}", this->pHandle_->GetPath());
|
||||
}
|
||||
|
||||
return nonblock;
|
||||
}
|
||||
|
||||
offset += written;
|
||||
length -= written;
|
||||
}
|
||||
|
||||
SysPushErrorMem();
|
||||
return false;
|
||||
if (!offset)
|
||||
{
|
||||
return nonblock;
|
||||
}
|
||||
|
||||
read.outVariable = tmp;
|
||||
@ -473,6 +502,11 @@ namespace Aurora::IO::IPC
|
||||
return {};
|
||||
}
|
||||
|
||||
if (object->bDead)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
@ -574,14 +608,17 @@ namespace Aurora::IO::IPC
|
||||
return {};
|
||||
}
|
||||
|
||||
if (object->bDead)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
mutex->WaitOn(0);
|
||||
|
||||
if (event->IsSignaled())
|
||||
{
|
||||
mutex->Unlock();
|
||||
SysPushErrorIO("Pipe Busy");
|
||||
::close(fds[0]);
|
||||
::close(fds[1]);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ namespace Aurora::IO::IPC
|
||||
AuUInt GetPreemptFd();
|
||||
|
||||
bool bIsSendingZero {};
|
||||
|
||||
bool bDead {};
|
||||
private:
|
||||
int fds[2] {-1, -1};
|
||||
int secondary[2] {-1, -1};
|
||||
|
Loading…
Reference in New Issue
Block a user