@@ -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(); | |||