diff --git a/modules/juce_core/native/juce_posix_NamedPipe.cpp b/modules/juce_core/native/juce_posix_NamedPipe.cpp index e0ca3024e8..45a9f8a581 100644 --- a/modules/juce_core/native/juce_posix_NamedPipe.cpp +++ b/modules/juce_core/native/juce_posix_NamedPipe.cpp @@ -33,6 +33,8 @@ public: : pipeInName (pipePath + "_in"), pipeOutName (pipePath + "_out"), pipeIn (-1), pipeOut (-1), + createdFifoIn (false), + createdFifoOut (false), createdPipe (createPipe), stopReadOperation (false) { @@ -47,8 +49,8 @@ public: if (createdPipe) { - unlink (pipeInName.toUTF8()); - unlink (pipeOutName.toUTF8()); + if (createdFifoIn) unlink (pipeInName.toUTF8()); + if (createdFifoOut) unlink (pipeOutName.toUTF8()); } } @@ -119,14 +121,22 @@ public: return bytesWritten; } - bool createFifos() const + static bool createFifo (const String& name, bool mustNotExist) { - return (mkfifo (pipeInName .toUTF8(), 0666) == 0 || errno == EEXIST) - && (mkfifo (pipeOutName.toUTF8(), 0666) == 0 || errno == EEXIST); + return mkfifo (name.toUTF8(), 0666) == 0 || ((! mustNotExist) && errno == EEXIST); + } + + bool createFifos (bool mustNotExist) + { + createdFifoIn = createFifo (pipeInName, mustNotExist); + createdFifoOut = createFifo (pipeOutName, mustNotExist); + + return createdFifoIn && createdFifoOut; } const String pipeInName, pipeOutName; int pipeIn, pipeOut; + bool createdFifoIn, createdFifoOut; const bool createdPipe; bool stopReadOperation; @@ -188,7 +198,7 @@ void NamedPipe::close() } } -bool NamedPipe::openInternal (const String& pipeName, const bool createPipe) +bool NamedPipe::openInternal (const String& pipeName, const bool createPipe, bool mustNotExist) { #if JUCE_IOS pimpl = new Pimpl (File::getSpecialLocation (File::tempDirectory) @@ -202,7 +212,7 @@ bool NamedPipe::openInternal (const String& pipeName, const bool createPipe) pimpl = new Pimpl (file, createPipe); #endif - if (createPipe && ! pimpl->createFifos()) + if (createPipe && ! pimpl->createFifos (mustNotExist)) { pimpl = nullptr; return false; diff --git a/modules/juce_core/native/juce_win32_Files.cpp b/modules/juce_core/native/juce_win32_Files.cpp index c3684f19e5..5408efaeaa 100644 --- a/modules/juce_core/native/juce_win32_Files.cpp +++ b/modules/juce_core/native/juce_win32_Files.cpp @@ -788,7 +788,7 @@ void File::revealToUser() const class NamedPipe::Pimpl { public: - Pimpl (const String& pipeName, const bool createPipe) + Pimpl (const String& pipeName, const bool createPipe, bool mustNotExist) : filename ("\\\\.\\pipe\\" + File::createLegalFileName (pipeName)), pipeH (INVALID_HANDLE_VALUE), cancelEvent (CreateEvent (0, FALSE, FALSE, 0)), @@ -800,7 +800,7 @@ public: PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0, PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, 0); - if (GetLastError() == ERROR_ALREADY_EXISTS) + if (mustNotExist && GetLastError() == ERROR_ALREADY_EXISTS) closePipeHandle(); } } @@ -995,9 +995,9 @@ void NamedPipe::close() } } -bool NamedPipe::openInternal (const String& pipeName, const bool createPipe) +bool NamedPipe::openInternal (const String& pipeName, const bool createPipe, bool mustNotExist) { - pimpl = new Pimpl (pipeName, createPipe); + pimpl = new Pimpl (pipeName, createPipe, mustNotExist); if (createPipe && pimpl->pipeH == INVALID_HANDLE_VALUE) { diff --git a/modules/juce_core/network/juce_NamedPipe.cpp b/modules/juce_core/network/juce_NamedPipe.cpp index bb580f77df..d498ed158e 100644 --- a/modules/juce_core/network/juce_NamedPipe.cpp +++ b/modules/juce_core/network/juce_NamedPipe.cpp @@ -41,7 +41,7 @@ bool NamedPipe::openExisting (const String& pipeName) ScopedWriteLock sl (lock); currentPipeName = pipeName; - return openInternal (pipeName, false); + return openInternal (pipeName, false, false); } bool NamedPipe::isOpen() const @@ -49,13 +49,13 @@ bool NamedPipe::isOpen() const return pimpl != nullptr; } -bool NamedPipe::createNewPipe (const String& pipeName) +bool NamedPipe::createNewPipe (const String& pipeName, bool mustNotExist) { close(); ScopedWriteLock sl (lock); currentPipeName = pipeName; - return openInternal (pipeName, true); + return openInternal (pipeName, true, mustNotExist); } String NamedPipe::getName() const diff --git a/modules/juce_core/network/juce_NamedPipe.h b/modules/juce_core/network/juce_NamedPipe.h index 9b957c38e9..b0973fcdf0 100644 --- a/modules/juce_core/network/juce_NamedPipe.h +++ b/modules/juce_core/network/juce_NamedPipe.h @@ -56,8 +56,10 @@ public: /** Tries to create a new pipe. Returns true if it succeeds. + If mustNotExist is true then it will fail if a pipe is already + open with the same name. */ - bool createNewPipe (const String& pipeName); + bool createNewPipe (const String& pipeName, bool mustNotExist = false); /** Closes the pipe, if it's open. */ void close(); @@ -95,7 +97,7 @@ private: String currentPipeName; ReadWriteLock lock; - bool openInternal (const String& pipeName, const bool createPipe); + bool openInternal (const String& pipeName, bool createPipe, bool mustNotExist); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NamedPipe) }; diff --git a/modules/juce_events/interprocess/juce_InterprocessConnection.cpp b/modules/juce_events/interprocess/juce_InterprocessConnection.cpp index 34f5c5dcab..70ac59ca26 100644 --- a/modules/juce_events/interprocess/juce_InterprocessConnection.cpp +++ b/modules/juce_events/interprocess/juce_InterprocessConnection.cpp @@ -91,13 +91,13 @@ bool InterprocessConnection::connectToPipe (const String& pipeName, const int ti return false; } -bool InterprocessConnection::createPipe (const String& pipeName, const int timeoutMs) +bool InterprocessConnection::createPipe (const String& pipeName, const int timeoutMs, bool mustNotExist) { disconnect(); ScopedPointer newPipe (new NamedPipe()); - if (newPipe->createNewPipe (pipeName)) + if (newPipe->createNewPipe (pipeName, mustNotExist)) { const ScopedLock sl (pipeAndSocketLock); pipeReceiveMessageTimeout = timeoutMs; diff --git a/modules/juce_events/interprocess/juce_InterprocessConnection.h b/modules/juce_events/interprocess/juce_InterprocessConnection.h index d2fdcd6988..280ad54a90 100644 --- a/modules/juce_events/interprocess/juce_InterprocessConnection.h +++ b/modules/juce_events/interprocess/juce_InterprocessConnection.h @@ -108,13 +108,14 @@ public: This creates a pipe with the given name, so that other processes can use connectToPipe() to connect to the other end. - @param pipeName the name to use for the pipe - this should be unique to your app + @param pipeName the name to use for the pipe - this should be unique to your app @param pipeReceiveMessageTimeoutMs a timeout length to be used when reading or writing - to the pipe, or -1 for an infinite timeout. + to the pipe, or -1 for an infinite timeout + @param mustNotExist if set to true, the method will fail if the pipe already exists @returns true if the pipe was created, or false if it fails (e.g. if another process is - already using using the pipe). + already using using the pipe) */ - bool createPipe (const String& pipeName, int pipeReceiveMessageTimeoutMs); + bool createPipe (const String& pipeName, int pipeReceiveMessageTimeoutMs, bool mustNotExist = false); /** Disconnects and closes any currently-open sockets or pipes. */ void disconnect();