From 1f173a879970df05866ceee435982024b4ef7081 Mon Sep 17 00:00:00 2001 From: J Reece Wilson Date: Fri, 11 Aug 2023 16:51:42 +0100 Subject: [PATCH] [*] Begin resolving 8 months of Linux neglect --- Include/Aurora/Async/AuFutures.hpp | 4 +- .../Threading/Primitives/SOOPrimitives.hpp | 38 ++- Source/Async/Schedular.cpp | 5 +- Source/AuCrypto.cpp | 1 - Source/AuRTEntrypoint.cpp | 3 +- .../Compressors/BrotliCompressor.hpp | 2 +- Source/Debug/ExceptionWatcher.Unix.cpp | 5 +- Source/Grug/AuArrow.cpp | 8 +- Source/IO/AuIOHandle.NT.cpp | 1 + Source/IO/AuIOHandle.Unix.cpp | 174 ++++++++++++++ Source/IO/AuIOHandle.Unix.hpp | 13 ++ Source/IO/AuIOHandle.hpp | 7 + Source/IO/FS/Async.Linux.cpp | 217 +++++++----------- Source/IO/FS/Async.Linux.hpp | 31 +-- Source/IO/FS/FS.Unix.cpp | 10 +- Source/IO/FS/FSTimes.Unix.cpp | 4 +- Source/IO/FS/FileAttrs.Unix.cpp | 14 +- Source/IO/FS/FileStream.Unix.cpp | 216 ++++++++++------- Source/IO/FS/FileStream.Unix.hpp | 9 +- Source/IO/FS/FileTrust.Unix.cpp | 4 + Source/IO/IPC/AuIPCPipe.Unix.cpp | 16 +- Source/IO/IPC/AuIPCPipe.Unix.hpp | 5 +- Source/IO/Net/AuNetSocket.Unix.cpp | 57 ++++- Source/IO/Net/AuNetSocket.Unix.hpp | 7 + Source/IO/UNIX/IOSubmit.Linux.cpp | 20 +- Source/Process/AuProcessEnvironment.Unix.cpp | 2 +- Source/Process/AuProcessMap.Linux.cpp | 14 +- .../AuProcessSectionFileMapView.Unix.cpp | 4 +- Source/Process/AuProcessSectionView.Unix.cpp | 37 ++- Source/Process/AuProcessSectionView.Unix.hpp | 4 +- .../AuProcessSectionViewReserved.Unix.cpp | 62 +++-- .../AuProcessSectionViewReserved.Unix.hpp | 4 +- Source/Processes/AuProcess.Unix.cpp | 13 +- Source/Processes/AuProcess.Unix.hpp | 4 +- Source/RNG/AuRNGEntropy.cpp | 2 +- Source/Threading/AuWakeOnAddress.cpp | 21 +- .../Primitives/AuConditionVariable.Unix.cpp | 15 +- .../Primitives/AuConditionVariable.Unix.hpp | 18 +- Source/Threading/Primitives/AuMutex.Linux.cpp | 54 +++-- Source/Threading/Primitives/AuMutex.Linux.hpp | 7 +- Source/Threading/Primitives/AuMutex.Unix.cpp | 25 +- Source/Threading/Primitives/AuMutex.Unix.hpp | 2 +- .../Primitives/AuSemaphore.Linux.cpp | 2 +- .../Threading/Primitives/AuSemaphore.Unix.cpp | 2 +- Source/Threading/Threads/AuOSThread.cpp | 18 +- Source/Time/AuClock.cpp | 4 + Source/Time/Time.hpp | 9 +- 47 files changed, 815 insertions(+), 379 deletions(-) create mode 100644 Source/IO/AuIOHandle.Unix.cpp create mode 100644 Source/IO/AuIOHandle.Unix.hpp diff --git a/Include/Aurora/Async/AuFutures.hpp b/Include/Aurora/Async/AuFutures.hpp index 4a3e7108..8a98b27d 100644 --- a/Include/Aurora/Async/AuFutures.hpp +++ b/Include/Aurora/Async/AuFutures.hpp @@ -177,7 +177,7 @@ protected: friend struct __detail::FutureAccessor; - CppFun::B &GetValue() + typename CppFun::B &GetValue() { return value; } @@ -316,7 +316,7 @@ private: this->pid = AuAsync::GetCurrentWorkerPId(); } - CppFun::B value; + typename CppFun::B value; ErrorStore_t errorValue; AuThreadPrimitives::Mutex mutex; diff --git a/Include/Aurora/Threading/Primitives/SOOPrimitives.hpp b/Include/Aurora/Threading/Primitives/SOOPrimitives.hpp index 9675dd7e..68493cf3 100644 --- a/Include/Aurora/Threading/Primitives/SOOPrimitives.hpp +++ b/Include/Aurora/Threading/Primitives/SOOPrimitives.hpp @@ -35,6 +35,22 @@ namespace Aurora::Threading::Primitives static const auto kPrimitiveSize32NTCond = 20; static const auto kPrimitiveSize32NTCondMutex = 8; + static const auto kPrimitiveSize64LinuxMutex = 16; + static const auto kPrimitiveSize64LinuxSemaphore = 16; + static const auto kPrimitiveSize64LinuxCS = 128; + static const auto kPrimitiveSize64LinuxEvent = 152; + static const auto kPrimitiveSize64LinuxRWLock = 200; + static const auto kPrimitiveSize64LinuxCond = 88; + static const auto kPrimitiveSize64LinuxCondMutex = 48; + + static const auto kPrimitiveSize32LinuxMutex = 8; + static const auto kPrimitiveSize32LinuxSemaphore = 8; + static const auto kPrimitiveSize32LinuxCS = 128; + static const auto kPrimitiveSize32LinuxEvent = 152; + static const auto kPrimitiveSize32LinuxRWLock = 200; + static const auto kPrimitiveSize32LinuxCond = 88; + static const auto kPrimitiveSize32LinuxCondMutex = 48; + // TODO: Other platforms... #else @@ -64,13 +80,33 @@ namespace Aurora::Threading::Primitives #define AURT_ENABLE_HYPER_MUTEX +#elif defined(AURORA_PLATFORM_LINUX) + + static const auto kPrimitiveSize64Mutex = kPrimitiveSize64LinuxMutex; + static const auto kPrimitiveSize64Semaphore = kPrimitiveSize64LinuxSemaphore; + static const auto kPrimitiveSize64CS = kPrimitiveSize64LinuxCS; + static const auto kPrimitiveSize64Event = kPrimitiveSize64LinuxEvent; + static const auto kPrimitiveSize64RWLock = kPrimitiveSize64LinuxRWLock; + static const auto kPrimitiveSize64Cond = kPrimitiveSize64LinuxCond; + static const auto kPrimitiveSize64CondMutex = kPrimitiveSize64LinuxCondMutex; + + static const auto kPrimitiveSize32Mutex = kPrimitiveSize32LinuxMutex; + static const auto kPrimitiveSize32Semaphore = kPrimitiveSize32LinuxSemaphore; + static const auto kPrimitiveSize32CS = kPrimitiveSize32LinuxCS; + static const auto kPrimitiveSize32Event = kPrimitiveSize32LinuxEvent; + static const auto kPrimitiveSize32RWLock = kPrimitiveSize32LinuxRWLock; + static const auto kPrimitiveSize32Cond = kPrimitiveSize32LinuxCond; + static const auto kPrimitiveSize32CondMutex = kPrimitiveSize32LinuxCondMutex; + + #define AURT_ENABLE_HYPER_MUTEX + #else static const auto kPrimitiveSize64Mutex = kDefaultPrimitiveSize64; static const auto kPrimitiveSize64Semaphore = kDefaultPrimitiveSize64; static const auto kPrimitiveSize64CS = kDefaultPrimitiveSize64; static const auto kPrimitiveSize64Event = kDefaultPrimitiveSize64; - static const auto kPrimitiveSize64RWLock = kDefaultPrimitiveSize64; + static const auto kPrimitiveSize64RWLock = kDefaultPrimitiveSize64 * 2; static const auto kPrimitiveSize64Cond = kDefaultPrimitiveSize64; static const auto kPrimitiveSize64CondMutex = kDefaultPrimitiveSize64; diff --git a/Source/Async/Schedular.cpp b/Source/Async/Schedular.cpp index def3cdda..db805a49 100644 --- a/Source/Async/Schedular.cpp +++ b/Source/Async/Schedular.cpp @@ -187,7 +187,10 @@ namespace Aurora::Async void DeinitSched() { - gThread->SendExitSignal(); + if (gThread) + { + gThread->SendExitSignal(); + } gSchedCondvar->Broadcast(); gThread.reset(); } diff --git a/Source/AuCrypto.cpp b/Source/AuCrypto.cpp index ad5659fa..b950333b 100644 --- a/Source/AuCrypto.cpp +++ b/Source/AuCrypto.cpp @@ -21,7 +21,6 @@ namespace Crypto yarrow_start(&gPrng); gHashTiger = register_hash(&tiger_desc); - register_hash(&md5_desc); gHashSha1 = register_hash(&sha1_desc); gHashSha256 = register_hash(&sha256_desc); gHashSha384 = register_hash(&sha384_desc); diff --git a/Source/AuRTEntrypoint.cpp b/Source/AuRTEntrypoint.cpp index c830febe..8df0033f 100644 --- a/Source/AuRTEntrypoint.cpp +++ b/Source/AuRTEntrypoint.cpp @@ -123,8 +123,9 @@ static void Pump() ::LinuxSuperSecretIOTick(); #endif - +#if defined(AURORA_PLATFORM_WIN32) Aurora::Win32DropSchedulerResolution(); +#endif } static void RuntimeLateClean(); diff --git a/Source/Compression/Compressors/BrotliCompressor.hpp b/Source/Compression/Compressors/BrotliCompressor.hpp index 438ad80e..57e5247d 100644 --- a/Source/Compression/Compressors/BrotliCompressor.hpp +++ b/Source/Compression/Compressors/BrotliCompressor.hpp @@ -197,7 +197,7 @@ namespace Aurora::Compression { size_t outNext {}; uint8_t *pOut {}; - while (outNext == 0 || BrotliEncoderHasMoreOutput(this->pState)); + while (outNext == 0 || BrotliEncoderHasMoreOutput(this->pState)) { auto [pMainDOut, uMainDOutLength] = this->GetDOutPair(); diff --git a/Source/Debug/ExceptionWatcher.Unix.cpp b/Source/Debug/ExceptionWatcher.Unix.cpp index 4f81518a..6bed8ee8 100644 --- a/Source/Debug/ExceptionWatcher.Unix.cpp +++ b/Source/Debug/ExceptionWatcher.Unix.cpp @@ -10,12 +10,11 @@ namespace Aurora::Debug { - void PlatformHandleFatal(bool fatal) + void PlatformHandleFatal(bool fatal, bool bNoExit) { - + } - void InitUNIX() { diff --git a/Source/Grug/AuArrow.cpp b/Source/Grug/AuArrow.cpp index 61b234cd..b6d86c52 100644 --- a/Source/Grug/AuArrow.cpp +++ b/Source/Grug/AuArrow.cpp @@ -39,10 +39,10 @@ namespace Aurora::Grug pArrow->pCallback = pCallback; pArrow->pCallbackRunaway = pCallbackRunaway; - #if defined(ARROW_NO_MUTEX) - SignalSafeSleepLockYield(&pArrow->spinSemaphore); - #else + #if !defined(ARROW_NO_MUTEX) SignalSafeSleepLockYield(pArrow->spinSemaphore2.AsPointer()); + #else + SignalSafeSleepLockYield(&pArrow->spinSemaphore); #endif { @@ -113,7 +113,9 @@ namespace Aurora::Grug auto lastCallback = last->pCallbackRunaway; last->spinSemaphore.Unlock(); + #if !defined(ARROW_NO_MUTEX) last->spinSemaphore2->Unlock(); + #endif gReservedArrows.pop_back(); diff --git a/Source/IO/AuIOHandle.NT.cpp b/Source/IO/AuIOHandle.NT.cpp index 3361f158..3122712f 100644 --- a/Source/IO/AuIOHandle.NT.cpp +++ b/Source/IO/AuIOHandle.NT.cpp @@ -93,6 +93,7 @@ namespace Aurora::IO if (create.bDirectIOMode) { dwFlags |= FILE_FLAG_NO_BUFFERING; + this->bDirectIOMode = true; } if (!dwFlags) diff --git a/Source/IO/AuIOHandle.Unix.cpp b/Source/IO/AuIOHandle.Unix.cpp new file mode 100644 index 00000000..9a7de9b9 --- /dev/null +++ b/Source/IO/AuIOHandle.Unix.cpp @@ -0,0 +1,174 @@ +/*** + Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: AuIOHandle.Unix.cpp + Date: 2023-8-11 + Author: Reece +***/ +#include +#include "AuIOHandle.hpp" +#include "AuIOHandle.Unix.hpp" + +#include "FS/FS.hpp" +#include "FS/FileAdvisory.Unix.hpp" +#include "FS/FileStream.Unix.hpp" + +#include + +namespace Aurora::IO +{ + AuUInt64 AFileHandle::DupHandle(AuUInt64 uOSHandle, bool bWriteAccess) + { + int fd = dup(uOSHandle); + + if (fd < 0) + { + return 0; + } + + return AuUInt64(fd); + } + + void AFileHandle::CloseHandle(AuUInt64 uOSHandle) + { + int fd = (int)uOSHandle; + if (fd < 0) + { + return; + } + + ::close(fd); + } + + struct UnixIOHandle final : AFileHandle + { + bool InitFromPath(HandleCreate create) override + { + int iFileDescriptor { -1 }; + + if (create.path.empty()) + { + SysPushErrorArg("Cannot open an IO handle to the provided empty path"); + return false; + } + + if (!FS::EFileOpenModeIsValid(create.eMode)) + { + SysPushErrorParam("Invalid open mode"); + return false; + } + + if (!FS::EFileAdvisoryLockLevelIsValid(create.eAdvisoryLevel)) + { + SysPushErrorParam("Invalid lock mode"); + return false; + } + + auto pathex = FS::NormalizePathRet(create.path); + if (pathex.empty()) + { + SysPushErrorMemory(); + return false; + } + + if (create.bAsyncHandle || + create.bDirectIOMode) + { + this->bDirectIO = true; + } + + switch (create.eMode) + { + case FS::EFileOpenMode::eRead: + { + + break; + } + case FS::EFileOpenMode::eReadWrite: + case FS::EFileOpenMode::eWrite: + { + if (create.bAlwaysCreateDirTree) + { + FS::CreateDirectories(pathex, true); + } + + if (create.bFailIfNonEmptyFile) + { + if (AuFS::FileExists(pathex.c_str())) + { + SysPushErrorResourceExists("File {} already exists", create.path); + return false; + } + } + + break; + } + }; + + iFileDescriptor = ::open(pathex.c_str(), + (create.eMode == FS::EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT)) | O_CLOEXEC | (this->bDirectIO ? O_DIRECT : 0), + 0664); + + if (iFileDescriptor < 0) + { + SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno); + return false; + } + + if (!FS::ApplyDumbAdvisoryLock(iFileDescriptor, create.eAdvisoryLevel)) + { + SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path); + ::close(iFileDescriptor); + return false; + } + + if (create.bFailIfNonEmptyFile) + { + if (FS::PosixGetLength(iFileDescriptor)) + { + SysPushErrorResourceExists("File {} already exists", create.path); + ::close(iFileDescriptor); + return false; + } + } + + switch (create.eMode) + { + case FS::EFileOpenMode::eRead: + { + this->uOSReadHandle = AuUInt64(iFileDescriptor); + break; + } + case FS::EFileOpenMode::eReadWrite: + { + this->uOSWriteHandle = AuUInt64(iFileDescriptor); + this->uOSReadHandle = AuUInt64(iFileDescriptor); + break; + } + case FS::EFileOpenMode::eWrite: + { + this->uOSWriteHandle = AuUInt64(iFileDescriptor); + break; + } + }; + + this->bIsAsync = create.bAsyncHandle; + + this->path = create.path; + + return this->IsValid(); + } + }; + + AUKN_SYM IIOHandle *IOHandleNew() + { + return _new UnixIOHandle(); + } + + AUKN_SYM void IOHandleRelease(IIOHandle *pIOHandle) + { + AuSafeDelete(pIOHandle); + } + + AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, IOHandle, UnixIOHandle) +} \ No newline at end of file diff --git a/Source/IO/AuIOHandle.Unix.hpp b/Source/IO/AuIOHandle.Unix.hpp new file mode 100644 index 00000000..0d5df020 --- /dev/null +++ b/Source/IO/AuIOHandle.Unix.hpp @@ -0,0 +1,13 @@ +/*** + Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: AuIOHandle.Unix.hpp + Date: 2023-8-11 + Author: Reece +***/ +#pragma once + +namespace Aurora::IO +{ + +} \ No newline at end of file diff --git a/Source/IO/AuIOHandle.hpp b/Source/IO/AuIOHandle.hpp index 27d978b6..2a530d7d 100644 --- a/Source/IO/AuIOHandle.hpp +++ b/Source/IO/AuIOHandle.hpp @@ -7,6 +7,11 @@ ***/ #pragma once +namespace Aurora::IO::IPC +{ + struct IPCPipeImpl; +} + namespace Aurora::IO { struct AFileHandle : IIOHandle @@ -48,6 +53,8 @@ namespace Aurora::IO AuSPtr pThat; bool bIsAsync {}; AuString path; + IPC::IPCPipeImpl *pIPCPipe {}; + bool bDirectIO {}; protected: // Implement me: diff --git a/Source/IO/FS/Async.Linux.cpp b/Source/IO/FS/Async.Linux.cpp index 3191dd5f..a6ccbe99 100644 --- a/Source/IO/FS/Async.Linux.cpp +++ b/Source/IO/FS/Async.Linux.cpp @@ -17,9 +17,12 @@ #include "FileStream.Unix.hpp" #include "Async.Linux.hpp" #include +#include namespace Aurora::IO::FS { + #define IPC_PIPE AuStaticCast(this->pHandle_)->pIPCPipe + struct LinuxAsyncFileTransactionLoopSource : Aurora::IO::Loop::LSEvent { LinuxAsyncFileTransactionLoopSource(AuSPtr that); @@ -38,16 +41,16 @@ namespace Aurora::IO::FS AuList handles_; }; - LinuxAsyncFileTransactionLoopSource::LinuxAsyncFileTransactionLoopSource(AuSPtr that) : caller_(that), Loop::LSEvent(false, false, true) + LinuxAsyncFileTransactionLoopSource::LinuxAsyncFileTransactionLoopSource(AuSPtr that) : + caller_(that), + Loop::LSEvent(false, false, true) { if (that) { - auto possiblePipe = that->GetFileHandle()->pIPCPipe; - if (possiblePipe) + if (auto pPipe = AuStaticCast(that->GetFileHandle())->pIPCPipe) { this->bExMode = true; - - this->handles_ = {possiblePipe->GetPreemptFd(), Loop::LSEvent::GetHandle()}; + this->handles_ = {pPipe->GetPreemptFd(), Loop::LSEvent::GetHandle()}; } } } @@ -94,80 +97,9 @@ namespace Aurora::IO::FS { } - FileHandle::~FileHandle() + void LinuxAsyncFileStream::Init(const AuSPtr &handle) { - if ((this->readHandle != 0) && - (this->readHandle != -1)) - { - ::close(this->readHandle); - } - - if ((this->writeHandle != 0) && - (this->writeHandle != -1) && - (this->writeHandle != this->readHandle)) - { - ::close(this->writeHandle); - } - - this->readHandle = this->writeHandle = -1; - } - - bool FileHandle::Init(const AuString &path, EFileOpenMode openMode, bool bDirectIO, EFileAdvisoryLockLevel lock) - { - int fileHandle; - int fOpenMode; - - auto pathex = NormalizePathRet(path); - if (pathex.empty()) - { - return false; - } - - fOpenMode = openMode == EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT); - if (bDirectIO) - { - fOpenMode |= O_DIRECT; - } - - fileHandle = ::open(pathex.c_str(), - fOpenMode, - 0664); - - if (fileHandle == -1) - { - SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno); - return false; - } - - if (!ApplyDumbAdvisoryLock(fileHandle, lock)) - { - SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path); - return false; - } - - this->directIO = bDirectIO; - this->readHandle = this->writeHandle = fileHandle; - this->readOnly = openMode == EFileOpenMode::eRead; - return true; - } - - void FileHandle::Init(int read, int write) - { - this->readHandle = read; - this->writeHandle = write; - this->directIO = true; - this->readOnly = false; - } - - - AuSPtr LinuxAsyncFileStream::GetHandle() - { - return handle_; - } - - void LinuxAsyncFileStream::Init(const AuSPtr &handle) - { - this->handle_ = handle; + this->pHandle_ = handle; } AuSPtr LinuxAsyncFileStream::NewTransaction() @@ -178,7 +110,7 @@ namespace Aurora::IO::FS return {}; } - if (!shared->Init(this->handle_)) + if (!shared->Init(this->pHandle_)) { return {}; } @@ -188,32 +120,53 @@ namespace Aurora::IO::FS bool LinuxAsyncFileStream::BlockingTruncate(AuUInt64 length) { - return ::ftruncate(this->handle_->writeHandle, length) != -1; - } - - bool LinuxAsyncFileStream::BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters) - { - if (this->handle_->bReadLock) + auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe(); + if (!iOptSafe) { return false; } - if (this->handle_->pIPCPipe) + auto fd = (int)iOptSafe.Value(); + if (fd == -1) { - if (this->handle_->pIPCPipe->LIOS_PopOne()) + SysPushErrorUninitialized(); + return false; + } + + return ::ftruncate(fd, length) != -1; + } + + bool LinuxAsyncFileStream::BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters) + { + auto iOptSafe = this->pHandle_->GetOSReadHandleSafe(); + if (!iOptSafe) + { + return false; + } + + auto fd = (int)iOptSafe.Value(); + if (fd == -1) + { + SysPushErrorUninitialized(); + return false; + } + + if (IPC_PIPE) + { + if (IPC_PIPE->LIOS_PopOne()) { parameters.outVariable = 0; return true; } } - if (!PosixSetOffset(this->handle_->readHandle, offset)) + if (!PosixSetOffset(fd, offset)) { return false; } AuUInt32 read; - if (!PosixRead(this->handle_->readHandle, parameters.ptr, parameters.length, &read)) + if (!PosixRead(fd, parameters.ptr, parameters.length, &read)) { return false; } @@ -223,18 +176,26 @@ namespace Aurora::IO::FS bool LinuxAsyncFileStream::BlockingWrite(AuUInt64 offset, const Memory::MemoryViewStreamRead ¶meters) { - if (this->handle_->bWriteLock) + auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe(); + if (!iOptSafe) { return false; } - if (!PosixSetOffset(this->handle_->writeHandle, offset)) + auto fd = (int)iOptSafe.Value(); + if (fd == -1) + { + SysPushErrorUninitialized(); + return false; + } + + if (!PosixSetOffset(fd, offset)) { return false; } AuUInt32 read; - if (!PosixWrite(this->handle_->writeHandle, parameters.ptr, parameters.length, &read)) + if (!PosixWrite(fd, parameters.ptr, parameters.length, &read)) { return false; } @@ -242,9 +203,9 @@ namespace Aurora::IO::FS return true; } - bool LinuxAsyncFileTransaction::Init(const AuSPtr &handle) + bool LinuxAsyncFileTransaction::Init(const AuSPtr &handle) { - this->handle_ = handle; + this->pHandle_ = handle; this->loopSource_ = AuMakeShared(AuSharedFromThis()); return bool(this->loopSource_); } @@ -262,16 +223,16 @@ namespace Aurora::IO::FS return false; } - - auto fd = this->handle_->readHandle; - if (fd == -1) + auto iOptSafe = this->pHandle_->GetOSReadHandleSafe(); + if (!iOptSafe) { - SysPushErrorUninitialized(); return false; } - if (this->handle_->bReadLock) + auto fd = (int)iOptSafe.Value(); + if (fd == -1) { + SysPushErrorUninitialized(); return false; } @@ -293,9 +254,9 @@ namespace Aurora::IO::FS LIOS_Init(AuSharedFromThis()); SetMemory(memoryView); - if (this->handle_->pIPCPipe) + if (IPC_PIPE) { - if (this->handle_->pIPCPipe->LIOS_PopOne()) + if (IPC_PIPE->LIOS_PopOne()) { LIOS_SendProcess(0, false, errno); return true; @@ -304,7 +265,7 @@ namespace Aurora::IO::FS offset += this->uBaseOffset; - if (!UNIX::LinuxOverlappedSubmitRead(fd, offset, this, this->loopSource_.get(), bool(this->handle_->pIPCPipe))) + if (!UNIX::LinuxOverlappedSubmitRead(fd, offset, this, this->loopSource_.get(), bool(IPC_PIPE))) { LIOS_SendProcess(0, true, errno); return true; @@ -328,12 +289,13 @@ namespace Aurora::IO::FS return false; } - if (this->handle_->bWriteLock) + auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe(); + if (!iOptSafe) { return false; } - auto fd = this->handle_->writeHandle; + auto fd = (int)iOptSafe.Value(); if (fd == -1) { SysPushErrorUninitialized(); @@ -398,11 +360,11 @@ namespace Aurora::IO::FS if (read) { - if (this->handle_->pIPCPipe) + if (IPC_PIPE) { // Return value intentionally ignored // We just need to poke on read... - this->handle_->pIPCPipe->LIOS_PopOne(); + IPC_PIPE->LIOS_PopOne(); } } @@ -471,9 +433,9 @@ namespace Aurora::IO::FS return WaitMultiple(files, timeout); } - AuSPtr LinuxAsyncFileTransaction::GetFileHandle() + AuSPtr LinuxAsyncFileTransaction::GetFileHandle() { - return this->handle_; + return this->pHandle_; } AuSPtr LinuxAsyncFileTransaction::NewLoopSource() @@ -483,38 +445,35 @@ namespace Aurora::IO::FS AUKN_SYM IAsyncFileStream *OpenAsyncNew(const AuString &path, EFileOpenMode openMode, bool bDirectIO, EFileAdvisoryLockLevel lock) { - AuSPtr fileHandle; - LinuxAsyncFileStream *stream; - - if (path.empty()) + auto pHandle = AuIO::IOHandleShared(); + if (!pHandle) { - SysPushErrorParam("Empty path"); - return {}; + SysPushErrorMemory(); + return nullptr; } - if (!EFileOpenModeIsValid(openMode)) - { - SysPushErrorParam("Invalid open mode"); - return {}; - } + AuIO::IIOHandle::HandleCreate createhandle(path); + createhandle.eAdvisoryLevel = lock; + createhandle.eMode = openMode; + createhandle.bFailIfNonEmptyFile = false; + createhandle.bDirectIOMode = bDirectIO; + createhandle.bAsyncHandle = true; - fileHandle = AuMakeShared(); - if (!fileHandle->Init(path, openMode, bDirectIO, lock)) + if (!pHandle->InitFromPath(createhandle)) { SysPushErrorNested(); - return {}; + return nullptr; } - stream = _new LinuxAsyncFileStream(); - if (!stream) + auto pStream = _new LinuxAsyncFileStream(); + if (!pStream) { - SysPushErrorMem(); - return {}; + SysPushErrorMemory(); + return nullptr; } - stream->Init(fileHandle); - - return stream; + pStream->Init(pHandle); + return pStream; } AUKN_SYM void OpenAsyncRelease(IAsyncFileStream *handle) diff --git a/Source/IO/FS/Async.Linux.hpp b/Source/IO/FS/Async.Linux.hpp index c3a69451..ad39d85d 100644 --- a/Source/IO/FS/Async.Linux.hpp +++ b/Source/IO/FS/Async.Linux.hpp @@ -17,25 +17,6 @@ namespace Aurora::IO::FS struct LinuxAsyncFileTransaction; struct LinuxAsyncFileTransactionLoopSource; - struct FileHandle - { - ~FileHandle(); - - bool Init(const AuString &path, EFileOpenMode openMode, bool directIO, EFileAdvisoryLockLevel lock); - void Init(int read, int write); - - int readHandle {-1}; - int writeHandle {-1}; - - AuString path; - bool readOnly; - bool directIO; - IPC::IPCPipeImpl *pIPCPipe {}; - bool bNoOwns { false }; - bool bWriteLock { false }; - bool bReadLock { false }; - }; - struct LinuxAsyncFileStream : IAsyncFileStream { AuSPtr NewTransaction() override; @@ -43,12 +24,12 @@ namespace Aurora::IO::FS bool BlockingRead(AuUInt64 offset, const Memory::MemoryViewStreamWrite ¶meters) override; bool BlockingWrite(AuUInt64 offset, const Memory::MemoryViewStreamRead ¶meters) override; - void Init(const AuSPtr &handle); + void Init(const AuSPtr &handle); - AuSPtr GetHandle(); + AuSPtr GetHandle(); private: - AuSPtr handle_; + AuSPtr pHandle_; }; @@ -56,7 +37,7 @@ namespace Aurora::IO::FS { ~LinuxAsyncFileTransaction(); - bool Init(const AuSPtr &handle); + bool Init(const AuSPtr &handle); bool StartRead(AuUInt64 offset, const AuSPtr &memoryView) override; bool StartWrite(AuUInt64 offset, const AuSPtr &memoryView) override; @@ -78,14 +59,14 @@ namespace Aurora::IO::FS void Reset() override; void DispatchCb(); - AuSPtr GetFileHandle(); + AuSPtr GetFileHandle(); void SetBaseOffset(AuUInt64 uBaseOffset) override; virtual void LIOS_Process(AuUInt32 read, bool failure, int err, bool mark) override; private: - AuSPtr handle_; + AuSPtr pHandle_; AuUInt64 lastAbstractOffset_ {}; AuUInt32 lastFinishedStat_ {}; AuUInt64 uBaseOffset {}; diff --git a/Source/IO/FS/FS.Unix.cpp b/Source/IO/FS/FS.Unix.cpp index 5c2181ea..8f69a025 100755 --- a/Source/IO/FS/FS.Unix.cpp +++ b/Source/IO/FS/FS.Unix.cpp @@ -302,8 +302,8 @@ namespace Aurora::IO::FS AUKN_SYM bool Relink(const AuString &src, const AuString &dest) { auto normalizedDestPath = NormalizePathRet(dest); - CreateDirectories(destPathNormalized, true); - return ::rename(NormalizePathRet(src).c_str(), destPathNormalized.c_str()) != -1; + CreateDirectories(normalizedDestPath, true); + return ::rename(NormalizePathRet(src).c_str(), normalizedDestPath.c_str()) != -1; } #if defined(AURORA_IS_LINUX_DERIVED) @@ -419,9 +419,9 @@ namespace Aurora::IO::FS #if defined(AURORA_IS_LINUX_DERIVED) - stat.createdNs = AuTime::CTimeNSNormalize(s.st_ctime_nsec); - stat.modifiedNs = AuTime::CTimeNSNormalize(s.st_mtime_nsec); - stat.accessedNs = AuTime::CTimeNSNormalize(s.st_atime_nsec); + stat.createdNs = AuTime::CTimeNSNormalize(s.st_ctim.tv_nsec); + stat.modifiedNs = AuTime::CTimeNSNormalize(s.st_mtim.tv_nsec); + stat.accessedNs = AuTime::CTimeNSNormalize(s.st_atim.tv_nsec); #else stat.createdNs = AuMSToNS(Time::CTimeToMS(s.st_ctime)); stat.modifiedNs = AuMSToNS(Time::CTimeToMS(s.st_mtime)); diff --git a/Source/IO/FS/FSTimes.Unix.cpp b/Source/IO/FS/FSTimes.Unix.cpp index 6b66c211..6dad75d8 100644 --- a/Source/IO/FS/FSTimes.Unix.cpp +++ b/Source/IO/FS/FSTimes.Unix.cpp @@ -66,8 +66,8 @@ namespace Aurora::IO::FS timeval timeVals[2]; - ConvertFileTime(&timeVals[0], auStat.accessed, times.accessedNs); - ConvertFileTime(&timeVals[1], auStat.modified, times.modifiedNs); + ConvertFileTime(&timeVals[0], auStat.accessedNs, times.accessedNs); + ConvertFileTime(&timeVals[1], auStat.modifiedNs, times.modifiedNs); bool bRet = ::utimes(pathex.c_str(), timeVals) == 0; if (!bRet) diff --git a/Source/IO/FS/FileAttrs.Unix.cpp b/Source/IO/FS/FileAttrs.Unix.cpp index 3d1e58dc..27f25fb3 100644 --- a/Source/IO/FS/FileAttrs.Unix.cpp +++ b/Source/IO/FS/FileAttrs.Unix.cpp @@ -19,7 +19,7 @@ namespace Aurora::IO::FS AuString buffer; auto srcPath = NormalizePathRet(path); - if (pathex.empty()) + if (srcPath.empty()) { return {}; } @@ -30,7 +30,7 @@ namespace Aurora::IO::FS return {}; } - auto length = ::listxattr(srcPath.c_str(), attr.c_str(), buffer.data(), buffer.size(), 0 /*no follow symlinks*/); + auto length = ::listxattr(srcPath.c_str(), buffer.data(), buffer.size()); if (length < 0) { SysPushErrorIO("Error listing attributes"); @@ -51,12 +51,12 @@ namespace Aurora::IO::FS AuByteBuffer buffer; auto srcPath = NormalizePathRet(path); - if (pathex.empty()) + if (srcPath.empty()) { return {}; } - auto length = ::getxattr(srcPath.c_str(), attr.c_str(), nullptr, 0, 0 /*no follow symlinks*/); + auto length = ::getxattr(srcPath.c_str(), attr.c_str(), nullptr, 0); if (length < 0) { SysPushErrorIO("Error reading attribute"); @@ -74,7 +74,7 @@ namespace Aurora::IO::FS return {}; } - length = ::getxattr(srcPath.c_str(), attr.c_str(), buffer.base, length, 0 /*no follow symlinks*/); + length = ::getxattr(srcPath.c_str(), attr.c_str(), buffer.base, length); if (length < 0) { SysPushErrorIO("Error reading attribute"); @@ -89,7 +89,7 @@ namespace Aurora::IO::FS AUKN_SYM bool FileAttrsSet(const AuString &path, const AuString &attr, const Memory::MemoryViewRead &view) { auto srcPath = NormalizePathRet(path); - if (pathex.empty()) + if (srcPath.empty()) { return false; } @@ -112,7 +112,7 @@ namespace Aurora::IO::FS AUKN_SYM bool FileAttrsDel(const AuString &path, const AuString &attr) { auto srcPath = NormalizePathRet(path); - if (pathex.empty()) + if (srcPath.empty()) { return false; } diff --git a/Source/IO/FS/FileStream.Unix.cpp b/Source/IO/FS/FileStream.Unix.cpp index 79624d11..c91599ca 100755 --- a/Source/IO/FS/FileStream.Unix.cpp +++ b/Source/IO/FS/FileStream.Unix.cpp @@ -126,57 +126,81 @@ namespace Aurora::IO::FS Close(); } - bool PosixFileStream::Init(int handle, const AuString &path) + bool PosixFileStream::Init(AuSPtr pHandle) { AuCtorCode_t code; - - this->handle_ = handle; - this->path_ = AuTryConstruct(code, path); - if (!code) - { - return false; - } - + this->pHandle_ = pHandle; return true; } AuUInt64 PosixFileStream::GetOffset() { AU_LOCK_GUARD(this->spinlock_); - - if (this->handle_ == -1) + + auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe(); + if (!iOptSafe) { - SysPushErrorUninitialized(); - return 0; + iOptSafe = this->pHandle_->GetOSReadHandleSafe(); } - return PosixGetOffset(this->handle_); + if (!iOptSafe) + { + return false; + } + + auto fd = (int)iOptSafe.Value(); + if (fd == -1) + { + SysPushErrorUninitialized(); + return false; + } + + return PosixGetOffset(fd); } bool PosixFileStream::SetOffset(AuUInt64 offset) { AU_LOCK_GUARD(this->spinlock_); - - if (this->handle_ == -1) + + auto iOptSafe = this->pHandle_->GetOSWriteHandleSafe(); + if (!iOptSafe) + { + iOptSafe = this->pHandle_->GetOSReadHandleSafe(); + } + + if (!iOptSafe) { - SysPushErrorUninitialized(); - return 0; + return false; } - return PosixSetOffset(this->handle_, offset); + auto fd = (int)iOptSafe.Value(); + if (fd == -1) + { + SysPushErrorUninitialized(); + return false; + } + + return PosixSetOffset(fd, offset); } AuUInt64 PosixFileStream::GetLength() { AU_LOCK_GUARD(this->spinlock_); - - if (this->handle_ == -1) + + auto iOptSafe = this->pHandle_->GetOSReadHandleSafe(); + if (!iOptSafe) + { + return false; + } + + auto fd = (int)iOptSafe.Value(); + if (fd == -1) { SysPushErrorUninitialized(); - return 0; + return false; } - return PosixGetLength(this->handle_); + return PosixGetLength(fd); } bool PosixFileStream::Read(const Memory::MemoryViewStreamWrite ¶meters) @@ -185,7 +209,14 @@ namespace Aurora::IO::FS parameters.outVariable = 0; - if (this->handle_ == -1) + if (!this->pHandle_) + { + SysPushErrorUninitialized(); + return 0; + } + + int fd = this->GetUnixHandle(); + if (fd == -1) { SysPushErrorUninitialized(); return 0; @@ -199,7 +230,7 @@ namespace Aurora::IO::FS int blockSize = AuMin(kFileCopyBlock, length); - if (!PosixRead(handle_, &reinterpret_cast(parameters.ptr)[offset], blockSize, &read)) + if (!PosixRead(fd, &reinterpret_cast(parameters.ptr)[offset], blockSize, &read)) { SysPushErrorNested("File Error: {}", path_); break; @@ -222,7 +253,14 @@ namespace Aurora::IO::FS { AU_LOCK_GUARD(this->spinlock_); - if (this->handle_ == -1) + if (!this->pHandle_) + { + SysPushErrorUninitialized(); + return 0; + } + + int fd = this->GetUnixHandle(); + if (fd == -1) { SysPushErrorUninitialized(); return 0; @@ -238,9 +276,9 @@ namespace Aurora::IO::FS int blockSize = AuMin(AuUInt(kFileCopyBlock), length); - if (!PosixWrite(this->handle_, &reinterpret_cast(parameters.ptr)[offset], blockSize, &written)) + if (!PosixWrite(fd, &reinterpret_cast(parameters.ptr)[offset], blockSize, &written)) { - SysPushErrorNested("File Error: {}", path_); + SysPushErrorNested("File Error: {}", this->pHandle_->GetPath()); return false; } @@ -265,26 +303,40 @@ namespace Aurora::IO::FS void PosixFileStream::Close() { - int handle = AuExchange(this->handle_, -1); - if (handle != -1) - { - ::close(handle); - } + auto pHandle = this->pHandle_; + AuResetMember(this->pHandle_); if (AuExchange(this->bMadeTemporary, false)) { - ::unlink(this->path_.c_str()); + if (pHandle) + { + ::unlink(pHandle->GetPath().c_str()); + } } } void PosixFileStream::Flush() { - ::fsync(this->handle_); + int fd = this->GetUnixHandle(); + if (fd == -1) + { + SysPushErrorUninitialized(); + return; + } + + ::fsync(fd); } void PosixFileStream::WriteEoS() { - ::ftruncate(this->handle_, GetOffset()); + int fd = this->GetUnixHandle(); + if (fd == -1) + { + SysPushErrorUninitialized(); + return; + } + + ::ftruncate(fd, GetOffset()); } void PosixFileStream::MakeTemporary() @@ -292,70 +344,72 @@ namespace Aurora::IO::FS this->bMadeTemporary = true; } - int PosixFileStream::GetHandle() + int PosixFileStream::GetUnixHandle() { - return this->handle_; + return this->pHandle_ ? + (int)this->pHandle_->GetOSWriteHandleSafe().ValueOr(this->pHandle_->GetOSReadHandleSafe().ValueOr((AuUInt)-1)) : + -1; } - static IFileStream *OpenNewEx(const AuString &path, EFileOpenMode openMode, EFileAdvisoryLockLevel lock, bool bCheck) + AuSPtr PosixFileStream::GetHandle() { - auto pathex = NormalizePathRet(path); + return this->pHandle_; + } - if (openMode != EFileOpenMode::eRead) + AUKN_SYM AuSPtr OpenBlockingFileStreamFromHandle(AuSPtr pIOHandle) + { + auto pStream = AuMakeShared(); + if (!pStream) { - CreateDirectories(pathex, true); + SysPushErrorMemory(); + return nullptr; } - if (bCheck) + pStream->Init(pIOHandle); + return pStream; + } + + static IFileStream *OpenNewEx(const AuString &path, + EFileOpenMode openMode, + EFileAdvisoryLockLevel lock, + bool bCheck) + { + try { - if (FileExists(path)) + auto pHandle = AuIO::IOHandleShared(); + if (!pHandle) { - SysPushErrorIO("Couldn't open file: {}. Already exists.", path); - return false; + SysPushErrorMemory(); + return nullptr; } - } - auto fileHandle = ::open(pathex.c_str(), - (openMode == EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT)) | O_CLOEXEC, - 0664); + AuIO::IIOHandle::HandleCreate createhandle(path); + createhandle.eAdvisoryLevel = lock; + createhandle.eMode = openMode; + createhandle.bFailIfNonEmptyFile = bCheck; + createhandle.bDirectIOMode = false; + createhandle.bAsyncHandle = false; - if (fileHandle < 0) - { - SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno); - return nullptr; - } - - if (!ApplyDumbAdvisoryLock(fileHandle, lock)) - { - SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path); - return nullptr; - } - - if (bCheck) - { - if (PosixGetLength(fileHandle)) + if (!pHandle->InitFromPath(createhandle)) { - SysPushErrorIO("Couldn't open file: {}. Already exists.", path); - return false; + SysPushErrorNested(); + return nullptr; } - } - auto stream = _new PosixFileStream(); - if (!stream) + auto pStream = _new PosixFileStream(); + if (!pStream) + { + SysPushErrorMemory(); + return nullptr; + } + + pStream->Init(pHandle); + return pStream; + } + catch (...) { - ::close(fileHandle); - SysPushErrorMem("{}", path); return nullptr; } - - if (!stream->Init(fileHandle, pathex)) - { - delete stream; - SysPushErrorGeneric("{}", path); - return nullptr; - } - - return stream; } AUKN_SYM IFileStream *CreateNew(const AuString &path) diff --git a/Source/IO/FS/FileStream.Unix.hpp b/Source/IO/FS/FileStream.Unix.hpp index decd8895..79fd38cc 100644 --- a/Source/IO/FS/FileStream.Unix.hpp +++ b/Source/IO/FS/FileStream.Unix.hpp @@ -13,6 +13,7 @@ namespace Aurora::IO::FS { // Code-sharing for async API fallbacks... bool PosixSetOffset(int fd, AuUInt64 offset); + AuUInt64 PosixGetLength(int fd); bool PosixRead(int fd, void *buf, AuUInt32 count, AuUInt32 *pRead); bool PosixWrite(int fd, const void *buf, AuUInt32 count, AuUInt32 *pWritten); @@ -20,7 +21,7 @@ namespace Aurora::IO::FS { ~PosixFileStream(); - bool Init(int handle, const AuString &path); + bool Init(AuSPtr pHandle); AuUInt64 GetOffset() override; bool SetOffset(AuUInt64 offset) override; @@ -31,11 +32,11 @@ namespace Aurora::IO::FS void Flush() override; void WriteEoS() override; void MakeTemporary() override; + AuSPtr GetHandle() override; + int GetUnixHandle(); - int GetHandle(); private: - - int handle_ = -1; + AuSPtr pHandle_; AuString path_; AuThreadPrimitives::SpinLock spinlock_; bool bMadeTemporary {}; diff --git a/Source/IO/FS/FileTrust.Unix.cpp b/Source/IO/FS/FileTrust.Unix.cpp index d5e0efdc..1226a866 100644 --- a/Source/IO/FS/FileTrust.Unix.cpp +++ b/Source/IO/FS/FileTrust.Unix.cpp @@ -10,6 +10,10 @@ #include "FileTrust.Unix.hpp" #include +#include +#include +#include +#include namespace Aurora::IO::FS { diff --git a/Source/IO/IPC/AuIPCPipe.Unix.cpp b/Source/IO/IPC/AuIPCPipe.Unix.cpp index e5f6e0ec..5fc00c31 100644 --- a/Source/IO/IPC/AuIPCPipe.Unix.cpp +++ b/Source/IO/IPC/AuIPCPipe.Unix.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace Aurora::IO::IPC { @@ -127,14 +128,16 @@ namespace Aurora::IO::IPC } #endif - this->fsHandle_ = AuMakeShared(); + + this->fsHandle_ = AuIO::IOHandleShared(); + SysAssert(this->fsHandle_); + this->fsStream_ = AuMakeShared(); - this->fsHandle_->pIPCPipe = this; + AuStaticCast(this->fsHandle_)->pIPCPipe = this; - this->fsHandle_->Init(fds2[0], fds2[1]); + this->fsHandle_->InitFromPairMove(fds2[0], fds2[1]); this->fsStream_->Init(this->fsHandle_); - } AuSPtr IPCPipeImpl::AsReadChannelIsOpen() @@ -152,6 +155,11 @@ namespace Aurora::IO::IPC return this->fsStream_->NewTransaction(); } + AuSPtr IPCPipeImpl::GetCurrentSharedDuplexHandles() + { + return this->fsHandle_; + } + bool IPCPipeImpl::Read(const Memory::MemoryViewStreamWrite &write, bool nonblock) { auto handle = fds[0]; diff --git a/Source/IO/IPC/AuIPCPipe.Unix.hpp b/Source/IO/IPC/AuIPCPipe.Unix.hpp index f4f7629f..b60fe671 100644 --- a/Source/IO/IPC/AuIPCPipe.Unix.hpp +++ b/Source/IO/IPC/AuIPCPipe.Unix.hpp @@ -53,7 +53,8 @@ namespace Aurora::IO::IPC #endif virtual AuSPtr NewAsyncTransaction() override; - + virtual AuSPtr GetCurrentSharedDuplexHandles() override; + virtual AuSPtr AsReadChannelIsOpen() override; virtual AuSPtr AsReadChannelHasData() override; @@ -84,7 +85,7 @@ namespace Aurora::IO::IPC int fds[2] {-1, -1}; int secondary[2] {-1, -1}; - AuSPtr fsHandle_; + AuSPtr fsHandle_; AuSPtr fsStream_; void SendTerminateSignal(); diff --git a/Source/IO/Net/AuNetSocket.Unix.cpp b/Source/IO/Net/AuNetSocket.Unix.cpp index 9097dc07..4f42ccb8 100644 --- a/Source/IO/Net/AuNetSocket.Unix.cpp +++ b/Source/IO/Net/AuNetSocket.Unix.cpp @@ -34,7 +34,16 @@ namespace Aurora::IO::Net Socket::Socket(struct NetInterface *pInterface, struct NetWorker *pWorker, const AuSPtr &pSocketDriver, - const NetEndpoint &endpoint) : + const AuPair &endpoint, + AuNet::ETransportProtocol eProtocol) : + SocketBase(pInterface, pWorker, pSocketDriver, endpoint, eProtocol) + { + } + + Socket::Socket(struct NetInterface *pInterface, + struct NetWorker *pWorker, + const AuSPtr &pSocketDriver, + const NetEndpoint &endpoint) : SocketBase(pInterface, pWorker, pSocketDriver, endpoint) { } @@ -55,14 +64,48 @@ namespace Aurora::IO::Net void Socket::CloseSocket() { - if (this->osHandle_ && - this->osHandle_ != -1) + this->osHandle_ = 0; + AuResetMember(this->osHandleOwner_); + } + + void Socket::RenewSocket() + { + if (!this->SendPreestablish()) { - ::close(this->osHandle_); - this->osHandle_ = 0; + SysPushErrorIO("Preestablish drop"); + return; + } + + if (this->bHasRemoteMany_ && this->connectMany_.ips.size()) + { + this->remoteEndpoint_ = this->connectMany_.ips[0]; + } + + this->CloseSocket(); + + this->osHandle_ = ::socket( + IPToDomain(this->remoteEndpoint_), + TransportToPlatformType(this->remoteEndpoint_), + 0 + ); + + if (this->osHandle_ == -1) + { + this->SendErrorNoStream(GetLastNetError()); + return; + } + + this->osHandleOwner_ = AuIO::IOHandleShared(); + this->osHandleOwner_->InitFromPairMove((int)this->osHandle_, (int)this->osHandle_); + + if (!this->PrepareConnectOperations()) + { + this->bForceFailConstruct_ = true; + return; } } + void Socket::FinishConstructAsync() { if (!this->SendPreestablish()) @@ -83,13 +126,13 @@ namespace Aurora::IO::Net return; } + this->osHandleOwner_->InitFromPairMove((int)this->osHandle_, (int)this->osHandle_); + if (!this->PrepareConnectOperations()) { this->bForceFailConstruct_ = true; return; } - - this->osHandleOwner_->Init((int)this->osHandle_, (int)this->osHandle_); } bool Socket::PrepareConnectOperations() diff --git a/Source/IO/Net/AuNetSocket.Unix.hpp b/Source/IO/Net/AuNetSocket.Unix.hpp index 36028e11..90dd5035 100644 --- a/Source/IO/Net/AuNetSocket.Unix.hpp +++ b/Source/IO/Net/AuNetSocket.Unix.hpp @@ -29,6 +29,12 @@ namespace Aurora::IO::Net const AuSPtr &pSocketDriver, AuUInt osHandle); + Socket(struct NetInterface *pInterface, + struct NetWorker *pWorker, + const AuSPtr &pSocketDriver, + const AuPair &endpoint, + AuNet::ETransportProtocol eProtocol); + Socket(struct NetInterface *pInterface, struct NetWorker *pWorker, const AuSPtr &pSocketDriver, @@ -61,6 +67,7 @@ namespace Aurora::IO::Net virtual void Shutdown(bool bNow) override; virtual void CloseSocket() override; + virtual void RenewSocket() override; bool MakeCloseonexec(); }; diff --git a/Source/IO/UNIX/IOSubmit.Linux.cpp b/Source/IO/UNIX/IOSubmit.Linux.cpp index dfc040e7..caecdee8 100644 --- a/Source/IO/UNIX/IOSubmit.Linux.cpp +++ b/Source/IO/UNIX/IOSubmit.Linux.cpp @@ -113,6 +113,8 @@ namespace Aurora::IO::UNIX { static bool LinuxOverlappedSubmit(int fd, int op, AuUInt offset, ASubmittable *context, AuLoop::ILSEvent *optEvent); + static void IoTlsRedo(); + ////////////////////////////////////////////////////////////////// // ASubmittable ////////////////////////////////////////////////////////////////// @@ -155,6 +157,8 @@ namespace Aurora::IO::UNIX { SysPushErrorCatch("IO Callback threw an exception"); } + + IoTlsRedo(); } UNIX::SendIOBuffers(); @@ -274,6 +278,7 @@ namespace Aurora::IO::UNIX aio_context_t context {}; AuList submitPendingArray; AuUInt32 dwIoSubmits; + bool bPollHit {}; ~TLSIO() { @@ -298,6 +303,17 @@ namespace Aurora::IO::UNIX return handle->bInitialized ? handle : nullptr; } + void IoTlsRedo() + { + auto pTLS = GetTls(); + if (!pTLS) + { + return; + } + + pTLS->bPollHit = true; + } + ////////////////////////////////////////////////////////////////// // TLS IO IMPL ////////////////////////////////////////////////////////////////// @@ -594,7 +610,7 @@ namespace Aurora::IO::UNIX } } - } while (timeout); + } while (timeout || AuExchange(io->bPollHit, false)); return dwApcsSent; } @@ -730,7 +746,7 @@ namespace Aurora::IO::UNIX } } - } while (timeout ? !bEpollTriggered : false); + } while ((timeout ? !bEpollTriggered : false) || AuExchange(io->bPollHit, false)); io_event finalEpollEvent {}; if ((bEpollTriggered) || diff --git a/Source/Process/AuProcessEnvironment.Unix.cpp b/Source/Process/AuProcessEnvironment.Unix.cpp index 5b7d79c9..cee24b68 100644 --- a/Source/Process/AuProcessEnvironment.Unix.cpp +++ b/Source/Process/AuProcessEnvironment.Unix.cpp @@ -39,7 +39,7 @@ namespace Aurora::Process if (key.empty()) { SysPushErrorArg("Missing key"); - return false; + return {}; } auto pValue = ::getenv(key.c_str()); diff --git a/Source/Process/AuProcessMap.Linux.cpp b/Source/Process/AuProcessMap.Linux.cpp index 1a87f5bc..50e87238 100644 --- a/Source/Process/AuProcessMap.Linux.cpp +++ b/Source/Process/AuProcessMap.Linux.cpp @@ -156,7 +156,6 @@ namespace Aurora::Process AuString file; AuIOFS::GetFileFromPath(file, path); - auto object = AuIOFS::OpenReadUnique(path); if (!object) { @@ -169,6 +168,7 @@ namespace Aurora::Process if (!object->Read(AuMemoryViewStreamWrite(AuMemoryViewWrite(&header, sizeof(header)), read))) { SysPushErrorIO(); + continue; } AuList elfSections; @@ -188,10 +188,15 @@ namespace Aurora::Process continue; } - auto &strtab = elfSections[header.e_shstrndx]; AuList strHeap; + if (strtab.sh_size > 80 * 1024 * 1024) + { + SysPushErrorMem(); + continue; + } + if (!AuTryResize(strHeap, strtab.sh_size)) { SysPushErrorMem(); @@ -211,6 +216,11 @@ namespace Aurora::Process Sections modSections; for (const auto & section : elfSections) { + if (section.sh_name > strHeap.size()) + { + continue; + } + auto len = strnlen((const char *)strHeap.data() + section.sh_name, strHeap.size() - section.sh_name); AuString sectionName((const char *)strHeap.data() + section.sh_name, len); AuUInt fileOffset = section.sh_offset; diff --git a/Source/Process/AuProcessSectionFileMapView.Unix.cpp b/Source/Process/AuProcessSectionFileMapView.Unix.cpp index c6cc8b80..e969ea4e 100644 --- a/Source/Process/AuProcessSectionFileMapView.Unix.cpp +++ b/Source/Process/AuProcessSectionFileMapView.Unix.cpp @@ -95,7 +95,7 @@ namespace Aurora::Process return false; } - return AuMemory::SwapLock::Lock({ { this->uAddress, this->uLength} }); + return AuMemory::SwapLock::Lock({ { this->uAddress, this->uLength_ } }); } bool ProcessSectionFileMapView::UnlockSwap() @@ -105,6 +105,6 @@ namespace Aurora::Process return false; } - return AuMemory::SwapLock::Unlock({ { this->uAddress, this->uLength} }); + return AuMemory::SwapLock::Unlock({ { this->uAddress, this->uLength_ } }); } } \ No newline at end of file diff --git a/Source/Process/AuProcessSectionView.Unix.cpp b/Source/Process/AuProcessSectionView.Unix.cpp index b704c0a0..11fa7a97 100644 --- a/Source/Process/AuProcessSectionView.Unix.cpp +++ b/Source/Process/AuProcessSectionView.Unix.cpp @@ -62,17 +62,16 @@ namespace Aurora::Process AuFS::EFileOpenMode mode, AuFS::EFileAdvisoryLockLevel sectionLock) { - auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety); - return file ? this->MapFileByObject(file, uOffset, uLength, mode, sectionLock) : AuSPtr {}; + return this->MapFileByPathEx(0, str, uOffset, uLength, mode, sectionLock); } - AuSPtr ProcessSectionView::MapFileByObject(const AuSPtr &stream, + AuSPtr ProcessSectionView::MapFileByObject(const AuSPtr &pIOHandle, AuUInt64 uOffset, AuUInt uLength, AuFS::EFileOpenMode mode, AuFS::EFileAdvisoryLockLevel processLockLevel) { - return this->MapFileByObjectEx(0, stream, uOffset, uLength, mode, processLockLevel); + return this->MapFileByObjectEx(0, pIOHandle, uOffset, uLength, mode, processLockLevel); } AuSPtr ProcessSectionView::MapIPCMemory(const AuString &handleString, @@ -144,18 +143,37 @@ namespace Aurora::Process Aurora::IO::FS::EFileOpenMode mode, Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) { - auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety); - return file ? this->MapFileByObjectEx(viewOffset, file, uOffset, uLength, mode, processLockLevel) : AuSPtr {}; + + auto pHandle = AuIO::IOHandleShared(); + if (!pHandle) + { + SysPushErrorMemory(); + return nullptr; + } + + AuIO::IIOHandle::HandleCreate createhandle(str); + createhandle.eAdvisoryLevel = AuFS::EFileAdvisoryLockLevel::eNoSafety; + createhandle.eMode = mode; + createhandle.bFailIfNonEmptyFile = false; + createhandle.bDirectIOMode = false; + createhandle.bAsyncHandle = false; + + if (!pHandle->InitFromPath(createhandle)) + { + return nullptr; + } + + return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, processLockLevel); } AuSPtr ProcessSectionView::MapFileByObjectEx(AuUInt viewOffset, - const AuSPtr &pStream, + const AuSPtr &pIOHandle, AuUInt64 uOffset, AuUInt uLength, Aurora::IO::FS::EFileOpenMode mode, Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) { - if (!pStream) + if (!pIOHandle) { return {}; } @@ -166,8 +184,7 @@ namespace Aurora::Process return {}; } - auto ok = AuStaticCast(pStream); - int fd = ::dup(ok->GetHandle()); + int fd = ::dup(pIOHandle->GetOSHandle()); if (fd == -1) { SysPushErrorIO(); diff --git a/Source/Process/AuProcessSectionView.Unix.hpp b/Source/Process/AuProcessSectionView.Unix.hpp index 25d1edc0..f042482a 100644 --- a/Source/Process/AuProcessSectionView.Unix.hpp +++ b/Source/Process/AuProcessSectionView.Unix.hpp @@ -23,7 +23,7 @@ namespace Aurora::Process AuFS::EFileOpenMode mode, AuFS::EFileAdvisoryLockLevel sectionLock) override; - AuSPtr MapFileByObject(const AuSPtr &stream, + AuSPtr MapFileByObject(const AuSPtr &pIOHandle, AuUInt64 offset, AuUInt length, Aurora::IO::FS::EFileOpenMode mode, @@ -46,7 +46,7 @@ namespace Aurora::Process Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) override; AuSPtr MapFileByObjectEx(AuUInt viewOffset, - const AuSPtr &pStream, + const AuSPtr &pIOHandle, AuUInt64 uOffset, AuUInt uLength, Aurora::IO::FS::EFileOpenMode mode, diff --git a/Source/Process/AuProcessSectionViewReserved.Unix.cpp b/Source/Process/AuProcessSectionViewReserved.Unix.cpp index 06cca7c9..bd441b3a 100644 --- a/Source/Process/AuProcessSectionViewReserved.Unix.cpp +++ b/Source/Process/AuProcessSectionViewReserved.Unix.cpp @@ -89,22 +89,21 @@ namespace Aurora::Process } AuSPtr ProcessSectionViewReserved::MapFileByPath(const AuString &str, - AuUInt64 uOffset, - AuUInt uLength, - AuFS::EFileOpenMode mode, - AuFS::EFileAdvisoryLockLevel sectionLock) + AuUInt64 uOffset, + AuUInt uLength, + AuFS::EFileOpenMode mode, + AuFS::EFileAdvisoryLockLevel sectionLock) { - auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety); - return file ? this->MapFileByObject(file, uOffset, uLength, mode, sectionLock) : AuSPtr {}; + return this->MapFileByPathEx(-1, str, uOffset, uLength, mode, sectionLock); } - AuSPtr ProcessSectionViewReserved::MapFileByObject(const AuSPtr &stream, + AuSPtr ProcessSectionViewReserved::MapFileByObject(const AuSPtr &pIOHandle, AuUInt64 uOffset, AuUInt uLength, AuFS::EFileOpenMode mode, AuFS::EFileAdvisoryLockLevel processLockLevel) { - return this->MapFileByObjectEx(-1, stream, uOffset, uLength, mode, processLockLevel); + return this->MapFileByObjectEx(-1, pIOHandle, uOffset, uLength, mode, processLockLevel); } AuSPtr ProcessSectionViewReserved::MapIPCMemory(const AuString &handleString, @@ -170,24 +169,42 @@ namespace Aurora::Process } AuSPtr ProcessSectionViewReserved::MapFileByPathEx(AuUInt viewOffset, - const AuString &str, - AuUInt64 uOffset, - AuUInt uLength, - Aurora::IO::FS::EFileOpenMode mode, - Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) + const AuString &str, + AuUInt64 uOffset, + AuUInt uLength, + Aurora::IO::FS::EFileOpenMode mode, + Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) { - auto file = AuFS::OpenShared(str, mode, AuFS::EFileAdvisoryLockLevel::eNoSafety); - return file ? this->MapFileByObjectEx(viewOffset, file, uOffset, uLength, mode, processLockLevel) : AuSPtr {}; + auto pHandle = AuIO::IOHandleShared(); + if (!pHandle) + { + SysPushErrorMemory(); + return nullptr; + } + + AuIO::IIOHandle::HandleCreate createhandle(str); + createhandle.eAdvisoryLevel = AuFS::EFileAdvisoryLockLevel::eNoSafety; + createhandle.eMode = mode; + createhandle.bFailIfNonEmptyFile = false; + createhandle.bDirectIOMode = false; + createhandle.bAsyncHandle = false; + + if (!pHandle->InitFromPath(createhandle)) + { + return nullptr; + } + + return this->MapFileByObjectEx(viewOffset, pHandle, uOffset, uLength, mode, processLockLevel); } AuSPtr ProcessSectionViewReserved::MapFileByObjectEx(AuUInt viewOffset, - const AuSPtr &pStream, - AuUInt64 uOffset, - AuUInt uLength, - Aurora::IO::FS::EFileOpenMode mode, - Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) + const AuSPtr &pIOHandle, + AuUInt64 uOffset, + AuUInt uLength, + Aurora::IO::FS::EFileOpenMode mode, + Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) { - if (!pStream) + if (!pIOHandle) { return {}; } @@ -204,8 +221,7 @@ namespace Aurora::Process return {}; } - auto ok = AuStaticCast(pStream); - int fd = ::dup(ok->GetHandle()); + int fd = ::dup(pIOHandle->GetOSHandle()); if (fd == -1) { SysPushErrorIO(); diff --git a/Source/Process/AuProcessSectionViewReserved.Unix.hpp b/Source/Process/AuProcessSectionViewReserved.Unix.hpp index 56b7c6af..4c3a44f9 100644 --- a/Source/Process/AuProcessSectionViewReserved.Unix.hpp +++ b/Source/Process/AuProcessSectionViewReserved.Unix.hpp @@ -30,7 +30,7 @@ namespace Aurora::Process AuFS::EFileOpenMode mode, AuFS::EFileAdvisoryLockLevel sectionLock) override; - AuSPtr MapFileByObject(const AuSPtr &stream, + AuSPtr MapFileByObject(const AuSPtr &pIOHandle, AuUInt64 offset, AuUInt length, Aurora::IO::FS::EFileOpenMode mode, @@ -53,7 +53,7 @@ namespace Aurora::Process Aurora::IO::FS::EFileAdvisoryLockLevel processLockLevel) override; AuSPtr MapFileByObjectEx(AuUInt viewOffset, - const AuSPtr &pStream, + const AuSPtr &pIOHandle, AuUInt64 uOffset, AuUInt uLength, Aurora::IO::FS::EFileOpenMode mode, diff --git a/Source/Processes/AuProcess.Unix.cpp b/Source/Processes/AuProcess.Unix.cpp index 7744da3b..c8f3dfe7 100644 --- a/Source/Processes/AuProcess.Unix.cpp +++ b/Source/Processes/AuProcess.Unix.cpp @@ -154,7 +154,7 @@ namespace Aurora::Processes { if (::kill(this->pidt_, SIGTERM) == 0) { - return this->finished_->Lock(500); + return this->finished_->LockMS(500); } } @@ -283,6 +283,9 @@ namespace Aurora::Processes fds[0] = ::open("/dev/null", O_RDWR); fds[1] = ::open("/dev/null", O_RDWR); break; + case EStreamForward::eNewConsoleWindow: + SysPushErrorGeneric("AuProcesses is not the right place for PTY support. At least not in this form (this level of abstraction only cares for pipes)."); + break; } return true; @@ -310,7 +313,7 @@ namespace Aurora::Processes if ((this->startup_.fwdIn == EStreamForward::eAsyncPipe) || (this->startup_.fwdOut == EStreamForward::eAsyncPipe)) { - this->fsHandle_ = AuMakeShared(); + this->fsHandle_ = AuIO::IOHandleShared(); if (!this->fsHandle_) { return false; @@ -322,13 +325,13 @@ namespace Aurora::Processes return false; } - this->fsHandle_->Init(this->pipeStdOut_[0], this->pipeStdIn_[1]); + this->fsHandle_->InitFromPairMove(this->pipeStdOut_[0], this->pipeStdIn_[1]); this->fsStream_->Init(this->fsHandle_); } if (this->startup_.fwdErr == EStreamForward::eAsyncPipe) { - this->fsErrorHandle_ = AuMakeShared(); + this->fsErrorHandle_ = AuIO::IOHandleShared(); if (!this->fsErrorHandle_) { return false; @@ -340,7 +343,7 @@ namespace Aurora::Processes return false; } - this->fsErrorHandle_->Init(this->pipeStdErr_[0], -1); + this->fsErrorHandle_->InitFromPairMove(this->pipeStdErr_[0], -1); this->fsErrorStream_->Init(this->fsErrorHandle_); } diff --git a/Source/Processes/AuProcess.Unix.hpp b/Source/Processes/AuProcess.Unix.hpp index ff2cc46c..84f8ffc5 100644 --- a/Source/Processes/AuProcess.Unix.hpp +++ b/Source/Processes/AuProcess.Unix.hpp @@ -66,10 +66,10 @@ namespace Aurora::Processes AuSPtr loopSource_; - AuSPtr fsHandle_; + AuSPtr fsHandle_; AuSPtr fsStream_; - AuSPtr fsErrorHandle_; + AuSPtr fsErrorHandle_; AuSPtr fsErrorStream_; AuThreadPrimitives::EventShared_t finished_; diff --git a/Source/RNG/AuRNGEntropy.cpp b/Source/RNG/AuRNGEntropy.cpp index 1d106313..16376897 100644 --- a/Source/RNG/AuRNGEntropy.cpp +++ b/Source/RNG/AuRNGEntropy.cpp @@ -175,7 +175,7 @@ namespace Aurora::RNG acc = a = b = c = 0; bits = 8; - void *pASLRSeed = &RngTimeBased; + void *pASLRSeed = (void *)&RngTimeBased; for (AU_ITERATE_N(uOffsetInByteStream, uLen)) { diff --git a/Source/Threading/AuWakeOnAddress.cpp b/Source/Threading/AuWakeOnAddress.cpp index 92b3ed74..654e7859 100644 --- a/Source/Threading/AuWakeOnAddress.cpp +++ b/Source/Threading/AuWakeOnAddress.cpp @@ -13,6 +13,12 @@ #include #endif +#if defined(AURORA_IS_LINUX_DERIVED) + #include + #include + #include +#endif + #include