| @@ -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; | |||
| @@ -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) | |||
| { | |||
| @@ -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 | |||
| @@ -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) | |||
| }; | |||
| @@ -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<NamedPipe> newPipe (new NamedPipe()); | |||
| if (newPipe->createNewPipe (pipeName)) | |||
| if (newPipe->createNewPipe (pipeName, mustNotExist)) | |||
| { | |||
| const ScopedLock sl (pipeAndSocketLock); | |||
| pipeReceiveMessageTimeout = timeoutMs; | |||
| @@ -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(); | |||