#include"qpipe.h" #ifdef Q_WS_WIN static uint readFromHandle(HANDLE h, char *buf, uint size) { if(size > 0) { ulong r; if(ReadFile(h, buf, size, &r, 0)) return r; } return 0; } #else #include #include #include #endif //---------------------------------------------------------------------------- // QPipeEnd //---------------------------------------------------------------------------- QPipeEnd::QPipeEnd() { reset(); } QPipeEnd::~QPipeEnd() { close(); } void QPipeEnd::reset() { #ifdef Q_WS_WIN p = 0; #else p = -1; #endif } bool QPipeEnd::isOpen() const { #ifdef Q_WS_WIN return (p ? true: false); #else return (p != -1 ? true: false); #endif } const QPipeId & QPipeEnd::id() const { return p; } void QPipeEnd::setId(const QPipeId &x) { p = x; } void QPipeEnd::close() { if(!isOpen()) return; #ifdef Q_WS_WIN CloseHandle(p); #else ::close(p); #endif reset(); } void QPipeEnd::release() { reset(); } QString QPipeEnd::toString() const { #ifdef Q_WS_WIN DWORD dw; memcpy(&dw, &p, sizeof(DWORD)); return QString::number(dw); #else return QString::number(p); #endif } int QPipeEnd::write(const QByteArray &buf) { #ifdef Q_WS_WIN DWORD written; if(!WriteFile(p, buf.data(), buf.size(), &written, 0)) return -1; return written; #else return (::write(p, buf.data(), buf.size())); #endif } QByteArray QPipeEnd::readAll(bool *done) { #ifdef Q_WS_WIN if(done) *done = false; unsigned long i, r; char dummy; if(!PeekNamedPipe(p, &dummy, 1, &r, &i, 0)) return QByteArray(); if(i <= 0) return QByteArray(); QByteArray buf; buf.resize(i); int size = readFromHandle(p, buf.data(), i); if(size == 0) return QByteArray(); return buf; #else if(done) *done = false; QByteArray buf; while(1) { char block[1024]; int n = read(p, block, 1024); if(n < 0) { if(errno == EAGAIN) { break; } else { if(done) *done = true; break; } } else if(n == 0) { if(done) *done = true; break; } int oldsize = buf.size(); buf.resize(oldsize + n); memcpy(buf.data() + oldsize, block, n); } return buf; #endif } #ifdef Q_WS_WIN bool QPipeEnd::winDupHandle() { HANDLE h; if(!DuplicateHandle(GetCurrentProcess(), p, GetCurrentProcess(), &h, 0, FALSE, DUPLICATE_SAME_ACCESS)) return false; CloseHandle(p); p = h; return true; } #else bool QPipeEnd::setBlock(bool b) { int flags = fcntl(p, F_GETFL); if(!b) flags |= O_NONBLOCK; else flags &= ~O_NONBLOCK; if(fcntl(p, F_SETFL, flags) == -1) return false; return true; } #endif //---------------------------------------------------------------------------- // QPipe //---------------------------------------------------------------------------- QPipe::QPipe() { } QPipe::~QPipe() { close(); } void QPipe::closeReadEnd() { i.close(); } void QPipe::closeWriteEnd() { o.close(); } int QPipe::write(const QByteArray &buf) { return o.write(buf); } QByteArray QPipe::readAll(bool *done) { return i.readAll(done); } bool QPipe::open() { close(); #ifdef Q_WS_WIN SECURITY_ATTRIBUTES secAttr; memset(&secAttr, 0, sizeof secAttr); secAttr.nLength = sizeof secAttr; secAttr.bInheritHandle = TRUE; HANDLE r, w; if(!CreatePipe(&r, &w, &secAttr, 0)) return false; i.setId(r); o.setId(w); #else int p[2]; if(pipe(p) == -1) return false; i.setId(p[0]); o.setId(p[1]); #endif return true; } void QPipe::close() { i.close(); o.close(); } void QPipe::release() { i.release(); o.release(); }