#include <QPipe.h>
Inheritance diagram for FX::QPipe:
This is one of the oldest pieces of code in my extensions to FOX - it was one of the first classes written for Tornado originally and it is a testament to how API compatible with Qt TnFOX is that very little work had to be done to port it. In fact, the below docs are almost identical too :)
QPipe is a synchronous i/o device like FX:QBlkSocket - in other words, reads from it block until data is available. To avoid this, check atEnd() before reading - however generally, you want it to block because you will have allocated a special thread whose sole purpose is to wait on incoming data and asynchronously do something useful with it. One action could be to post a message to some control in the GUI for example but more likely you'll combine it with FX::FXIPCMsgMonitorBase.
Reads and writes are threadsafe, but you should avoid more than two threads working with the same pipe (the same as more than two processes) because transfers occur in no more than maxAtomicLength() (usually 4096 bytes, but it is system dependent) - so two threads writing at the same time will cause the read data to be mixed blocks of data - which you probably don't want. If you do use a pipe which has more than two users, ensure all data transfers are less than maxAtomicLength(). If you want a pipe with less restrictions and only for intra-process communication, see FX::QLocalPipe. If you need less restrictions across multiple processes, see FX::QBlkSocket (though this is inefficient).
Default security is for FX::FXACLEntity::everything() to have full access. This makes sense as named pipes are generally for inter-process communication - if however it's a private pipe for communication with a known process it makes sense to restrict access to the user running that process at least. Note that until the pipe is opened, permissions() returns what will be applied to the pipe on open() rather than the pipe itself - if you want the latter, use the static method.
Like FX::QMemMap, the pipe name is deleted by its creator on POSIX only (on Windows it lasts until the last thing referring to it closes). If you don't want this, specify IO_DontUnlink in the flags to open().
To use is pretty easy - simply construct one, set its name and have your intended server process call create(). Then have your client process call open(). Reads block (wait indefinitely) until someone connects and sends some data. If you set the isDeepPipe
parameter on creation, extra deep buffers are set if supported by the host operating system.
If a pipe should break unexpectedly, a special informational exception FX::FXConnectionLostException is thrown which has a code of FXEXCEPTION_CONNECTIONLOST. You may or may not at this stage wish to call reset(). For anything more than non-trivial usage, you will need to trap and handle this in order to be handling errors correctly.
If you merely want some unique pipe for communication, use setUnique(). This chooses a randomised name and will retry rerandomised names until it finds one available during create(). Thereafter you can send its unique name (retrieved by name()) to the other process to open(). Note that reset() may rerandomise the name if it something else has claimed that name.
A major portability difference is that on Win32/64, named pipes are fundamentally broken in various minor ways plus must cope with thread cancellation. I originally spent many months getting this code to work around all the problems and make them behave like on Unix as much as possible - however it's possible I've missed some area. Please look at the source of QPipe to get some idea of the problems :(
Due to issues with cancelling overlapped i/o on Windows, close() the pipe from the same thread you last performed a read operation. Failure to do this results in free space corruption in the heap which may or may not have the CRT library throw an assertion when validating the MSVC heap. This bug took me two days to find, so I hope that you won't suffer the same!
Definition at line 109 of file QPipe.h.
Public Types | |
typedef FXfval | Offset |
Default | |
Unix | |
MacOS | |
MSDOS | |
NoTranslation | |
UTF8 | |
UTF16 | |
UTF16LE | |
UTF32 | |
UTF32LE | |
enum | CRLFType { Default, Unix, MacOS, MSDOS } |
enum | UnicodeType { NoTranslation, UTF8, UTF16, UTF16LE, UTF32, UTF32LE } |
Public Member Functions | |
QPipe () | |
QPipe (const FXString &name, bool isDeepPipe=false) | |
~QPipe () | |
const FXString & | name () const |
void | setName (const FXString &name) |
bool | isUnique () const |
void | setUnique (bool a) |
bool | create (FXuint mode=IO_ReadWrite) |
bool | open (FXuint mode=IO_ReadWrite) |
void | close () |
void | flush () |
bool | reset () |
bool | atEnd () const |
FXfval | size () const |
void | truncate (FXfval size) |
FXfval | at () const |
bool | at (FXfval newpos) |
virtual const FXACL & | permissions () const |
virtual void | setPermissions (const FXACL &perms) |
FXuval | readBlock (char *data, FXuval maxlen) |
FXuval | writeBlock (const char *data, FXuval maxlen) |
int | ungetch (int) |
FXuval | maxAtomicLength () |
virtual bool | isSynchronous () const |
virtual FXuval | readBlockFrom (char *data, FXuval maxlen, FXfval pos) |
FXuval | readBlockFrom (FXuchar *data, FXuval maxlen, FXfval pos) |
virtual FXuval | writeBlockTo (FXfval pos, const char *data, FXuval maxlen) |
FXuval | writeBlockTo (FXfval pos, const FXuchar *data, FXuval maxlen) |
FXuint | flags () const |
FXuint | mode () const |
FXuint | state () const |
CRLFType | crlfFormat () const |
void | setCRLFFormat (CRLFType type) |
UnicodeType | unicodeTranslation () const |
void | setUnicodeTranslation (UnicodeType type) |
bool | isBuffered () const |
bool | isRaw () const |
bool | isTranslated () const |
bool | isUTF16Translated () const |
bool | isUTF32Translated () const |
bool | isReadable () const |
bool | isWriteable () const |
bool | isWritable () const |
bool | isReadWrite () const |
bool | isClosed () const |
bool | isInactive () const |
bool | isOpen () const |
FXuval | readBlock (FXuchar *data, FXuval maxlen) |
FXuval | writeBlock (const FXuchar *data, FXuval maxlen) |
virtual FXuval | readLine (char *data, FXuval maxlen) |
virtual int | getch () |
virtual int | putch (int c) |
FXfval | shredData (FXfval offset, FXfval len=(FXfval)-1) |
Static Public Member Functions | |
static FXACL | permissions (const FXString &name) |
static void | setPermissions (const FXString &name, const FXACL &perms) |
static bool | waitForData (QIODeviceS **signalled, FXuint no, QIODeviceS **list, FXuint waitfor=FXINFINITE) |
static FXuint | waitForDataMax () throw () |
static UnicodeType | determineUnicodeType (FXuchar *data, FXuval len) throw () |
static FXuval | applyCRLF (FXuchar *FXRESTRICT output, const FXuchar *FXRESTRICT input, FXuval outputlen, FXuval &inputlen, CRLFType crlftype=Default, UnicodeType utftype=NoTranslation) |
static FXuval | removeCRLF (FXuchar *FXRESTRICT output, const FXuchar *FXRESTRICT input, FXuval outputlen, FXuval &inputlen, UnicodeType utftype=NoTranslation) |
Protected Member Functions | |
void | setFlags (int f) |
void | setMode (int m) |
void | setState (int s) |
Protected Attributes | |
FXfval | ioIndex |
Friends | |
class | FXIPCChannel |
class | QChildProcess |
struct | QChildProcessPrivate |
FXAPI FXStream & | operator<< (FXStream &s, QIODevice &i) |
FXAPI FXStream & | operator>> (FXStream &s, QIODevice &i) |