| @@ -33,6 +33,8 @@ public: | |||||
| : pipeInName (pipePath + "_in"), | : pipeInName (pipePath + "_in"), | ||||
| pipeOutName (pipePath + "_out"), | pipeOutName (pipePath + "_out"), | ||||
| pipeIn (-1), pipeOut (-1), | pipeIn (-1), pipeOut (-1), | ||||
| createdFifoIn (false), | |||||
| createdFifoOut (false), | |||||
| createdPipe (createPipe), | createdPipe (createPipe), | ||||
| stopReadOperation (false) | stopReadOperation (false) | ||||
| { | { | ||||
| @@ -47,8 +49,8 @@ public: | |||||
| if (createdPipe) | 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; | 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; | const String pipeInName, pipeOutName; | ||||
| int pipeIn, pipeOut; | int pipeIn, pipeOut; | ||||
| bool createdFifoIn, createdFifoOut; | |||||
| const bool createdPipe; | const bool createdPipe; | ||||
| bool stopReadOperation; | 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 | #if JUCE_IOS | ||||
| pimpl = new Pimpl (File::getSpecialLocation (File::tempDirectory) | 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); | pimpl = new Pimpl (file, createPipe); | ||||
| #endif | #endif | ||||
| if (createPipe && ! pimpl->createFifos()) | |||||
| if (createPipe && ! pimpl->createFifos (mustNotExist)) | |||||
| { | { | ||||
| pimpl = nullptr; | pimpl = nullptr; | ||||
| return false; | return false; | ||||
| @@ -788,7 +788,7 @@ void File::revealToUser() const | |||||
| class NamedPipe::Pimpl | class NamedPipe::Pimpl | ||||
| { | { | ||||
| public: | public: | ||||
| Pimpl (const String& pipeName, const bool createPipe) | |||||
| Pimpl (const String& pipeName, const bool createPipe, bool mustNotExist) | |||||
| : filename ("\\\\.\\pipe\\" + File::createLegalFileName (pipeName)), | : filename ("\\\\.\\pipe\\" + File::createLegalFileName (pipeName)), | ||||
| pipeH (INVALID_HANDLE_VALUE), | pipeH (INVALID_HANDLE_VALUE), | ||||
| cancelEvent (CreateEvent (0, FALSE, FALSE, 0)), | cancelEvent (CreateEvent (0, FALSE, FALSE, 0)), | ||||
| @@ -800,7 +800,7 @@ public: | |||||
| PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0, | PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0, | ||||
| PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, 0); | PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, 0); | ||||
| if (GetLastError() == ERROR_ALREADY_EXISTS) | |||||
| if (mustNotExist && GetLastError() == ERROR_ALREADY_EXISTS) | |||||
| closePipeHandle(); | 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) | if (createPipe && pimpl->pipeH == INVALID_HANDLE_VALUE) | ||||
| { | { | ||||
| @@ -41,7 +41,7 @@ bool NamedPipe::openExisting (const String& pipeName) | |||||
| ScopedWriteLock sl (lock); | ScopedWriteLock sl (lock); | ||||
| currentPipeName = pipeName; | currentPipeName = pipeName; | ||||
| return openInternal (pipeName, false); | |||||
| return openInternal (pipeName, false, false); | |||||
| } | } | ||||
| bool NamedPipe::isOpen() const | bool NamedPipe::isOpen() const | ||||
| @@ -49,13 +49,13 @@ bool NamedPipe::isOpen() const | |||||
| return pimpl != nullptr; | return pimpl != nullptr; | ||||
| } | } | ||||
| bool NamedPipe::createNewPipe (const String& pipeName) | |||||
| bool NamedPipe::createNewPipe (const String& pipeName, bool mustNotExist) | |||||
| { | { | ||||
| close(); | close(); | ||||
| ScopedWriteLock sl (lock); | ScopedWriteLock sl (lock); | ||||
| currentPipeName = pipeName; | currentPipeName = pipeName; | ||||
| return openInternal (pipeName, true); | |||||
| return openInternal (pipeName, true, mustNotExist); | |||||
| } | } | ||||
| String NamedPipe::getName() const | String NamedPipe::getName() const | ||||
| @@ -56,8 +56,10 @@ public: | |||||
| /** Tries to create a new pipe. | /** Tries to create a new pipe. | ||||
| Returns true if it succeeds. | 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. */ | /** Closes the pipe, if it's open. */ | ||||
| void close(); | void close(); | ||||
| @@ -95,7 +97,7 @@ private: | |||||
| String currentPipeName; | String currentPipeName; | ||||
| ReadWriteLock lock; | 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) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NamedPipe) | ||||
| }; | }; | ||||
| @@ -91,13 +91,13 @@ bool InterprocessConnection::connectToPipe (const String& pipeName, const int ti | |||||
| return false; | return false; | ||||
| } | } | ||||
| bool InterprocessConnection::createPipe (const String& pipeName, const int timeoutMs) | |||||
| bool InterprocessConnection::createPipe (const String& pipeName, const int timeoutMs, bool mustNotExist) | |||||
| { | { | ||||
| disconnect(); | disconnect(); | ||||
| ScopedPointer<NamedPipe> newPipe (new NamedPipe()); | ScopedPointer<NamedPipe> newPipe (new NamedPipe()); | ||||
| if (newPipe->createNewPipe (pipeName)) | |||||
| if (newPipe->createNewPipe (pipeName, mustNotExist)) | |||||
| { | { | ||||
| const ScopedLock sl (pipeAndSocketLock); | const ScopedLock sl (pipeAndSocketLock); | ||||
| pipeReceiveMessageTimeout = timeoutMs; | pipeReceiveMessageTimeout = timeoutMs; | ||||
| @@ -108,13 +108,14 @@ public: | |||||
| This creates a pipe with the given name, so that other processes can use | This creates a pipe with the given name, so that other processes can use | ||||
| connectToPipe() to connect to the other end. | 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 | @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 | @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. */ | /** Disconnects and closes any currently-open sockets or pipes. */ | ||||
| void disconnect(); | void disconnect(); | ||||