[svn] gpgme - r1267 - trunk/gpgme
svn author marcus
cvs at cvs.gnupg.org
Fri Sep 28 00:21:20 CEST 2007
Author: marcus
Date: 2007-09-28 00:21:10 +0200 (Fri, 28 Sep 2007)
New Revision: 1267
Modified:
trunk/gpgme/ChangeLog
trunk/gpgme/kdpipeiodevice.cpp
trunk/gpgme/kdpipeiodevice.moc
trunk/gpgme/w32-qt-io.cpp
Log:
2007-09-28 Marcus Brinkmann <marcus at g10code.de>
* kdpipeiodevice.moc, w32-qt-io.cpp, kdpipeiodevice.cpp: New
versions from Frank Osterfeld.
Modified: trunk/gpgme/ChangeLog
===================================================================
--- trunk/gpgme/ChangeLog 2007-09-27 13:01:54 UTC (rev 1266)
+++ trunk/gpgme/ChangeLog 2007-09-27 22:21:10 UTC (rev 1267)
@@ -1,3 +1,8 @@
+2007-09-28 Marcus Brinkmann <marcus at g10code.de>
+
+ * kdpipeiodevice.moc, w32-qt-io.cpp, kdpipeiodevice.cpp: New
+ versions from Frank Osterfeld.
+
2007-09-27 Marcus Brinkmann <marcus at g10code.de>
* w32-glib-io.c (_gpgme_io_spawn),
Modified: trunk/gpgme/kdpipeiodevice.cpp
===================================================================
--- trunk/gpgme/kdpipeiodevice.cpp 2007-09-27 13:01:54 UTC (rev 1266)
+++ trunk/gpgme/kdpipeiodevice.cpp 2007-09-27 22:21:10 UTC (rev 1267)
@@ -51,7 +51,7 @@
const bool ALLOW_QIODEVICE_BUFFERING = true;
// comment to get trace output:
-#define qDebug if(1){}else qDebug
+//#define qDebug if(1){}else qDebug
namespace {
class Reader : public QThread {
@@ -81,7 +81,7 @@
return true;
return false;
}
-
+
Q_SIGNALS:
void readyRead();
@@ -188,7 +188,8 @@
Writer::~Writer() {}
-class KDPipeIODevice::Private {
+class KDPipeIODevice::Private : public QObject {
+Q_OBJECT
friend class ::KDPipeIODevice;
KDPipeIODevice * const q;
public:
@@ -196,6 +197,11 @@
~Private();
bool doOpen( int, Qt::HANDLE, OpenMode );
+ bool startReaderThread();
+ bool startWriterThread();
+ void stopThreads();
+ bool triedToStartReader;
+ bool triedToStartWriter;
private:
int fd;
@@ -205,19 +211,18 @@
};
KDPipeIODevice::Private::Private( KDPipeIODevice * qq )
- : q( qq ),
+ : QObject( qq ), q( qq ),
fd( -1 ),
handle( 0 ),
reader( 0 ),
- writer( 0 )
+ writer( 0 ),
+ triedToStartReader( false ), triedToStartWriter( false )
{
}
-
KDPipeIODevice::Private::~Private() {}
-
KDPipeIODevice::KDPipeIODevice( QObject * p )
: QIODevice( p ), d( new Private( this ) )
{
@@ -267,6 +272,36 @@
}
+bool KDPipeIODevice::Private::startReaderThread()
+{
+ if ( triedToStartReader )
+ return true;
+ triedToStartReader = true;
+ if ( reader && !reader->isRunning() && !reader->isFinished() ) {
+ LOCKED( reader );
+
+ reader->start( QThread::HighestPriority );
+ if ( !reader->hasStarted.wait( &reader->mutex, 1000 ) )
+ return false;
+ }
+ return true;
+}
+
+bool KDPipeIODevice::Private::startWriterThread()
+{
+ if ( triedToStartWriter )
+ return true;
+ triedToStartWriter = true;
+ if ( writer && !writer->isRunning() && !writer->isFinished() ) {
+ LOCKED( writer );
+
+ writer->start( QThread::HighestPriority );
+ if ( !writer->hasStarted.wait( &writer->mutex, 1000 ) )
+ return false;
+ }
+ return true;
+}
+
bool KDPipeIODevice::Private::doOpen( int fd_, Qt::HANDLE handle_, OpenMode mode_ ) {
if ( q->isOpen() || fd_ < 0 )
@@ -288,19 +323,15 @@
if ( mode_ & ReadOnly ) {
reader_.reset( new Reader( fd_, handle_ ) );
- LOCKED( reader_ );
- reader_->start( QThread::HighestPriority );
- if ( !reader_->hasStarted.wait( &reader_->mutex, 1000 ) )
- return false;
- connect( reader_.get(), SIGNAL(readyRead()), q, SIGNAL(readyRead()), Qt::QueuedConnection );
+ qDebug( "KDPipeIODevice::doOpen: created reader for fd %d", fd_ );
+ connect( reader_.get(), SIGNAL(readyRead()), q,
+SIGNAL(readyRead()), Qt::QueuedConnection );
}
if ( mode_ & WriteOnly ) {
writer_.reset( new Writer( fd_, handle_ ) );
- LOCKED( writer_ );
- writer_->start( QThread::HighestPriority );
- if ( !writer_->hasStarted.wait( &writer_->mutex, 1000 ) )
- return false;
- connect( writer_.get(), SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64)), Qt::QueuedConnection );
+ qDebug( "KDPipeIODevice::doOpen: created writer for fd %d", fd_ );
+ connect( writer_.get(), SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64)),
+Qt::QueuedConnection );
}
// commit to *this:
@@ -310,7 +341,6 @@
writer = writer_.release();
q->setOpenMode( mode_|Unbuffered );
-
return true;
}
@@ -318,18 +348,24 @@
return d->fd;
}
+
Qt::HANDLE KDPipeIODevice::handle() const { KDAB_CHECK_THIS;
return d->handle;
}
qint64 KDPipeIODevice::bytesAvailable() const { KDAB_CHECK_THIS;
const qint64 base = QIODevice::bytesAvailable();
+ if ( !d->triedToStartReader ) {
+ d->startReaderThread();
+ return base;
+ }
if ( d->reader )
synchronized( d->reader ) return base + d->reader->bytesInBuffer();
return base;
}
qint64 KDPipeIODevice::bytesToWrite() const { KDAB_CHECK_THIS;
+ d->startWriterThread();
const qint64 base = QIODevice::bytesToWrite();
if ( d->writer )
synchronized( d->writer ) return base + d->writer->bytesInBuffer();
@@ -337,7 +373,8 @@
}
bool KDPipeIODevice::canReadLine() const { KDAB_CHECK_THIS;
- if ( QIODevice::canReadLine() )
+ d->startReaderThread();
+ if ( QIODevice::canReadLine() )
return true;
if ( d->reader )
synchronized( d->reader ) return d->reader->bufferContains( '\n' );
@@ -349,8 +386,9 @@
}
bool KDPipeIODevice::atEnd() const { KDAB_CHECK_THIS;
+ d->startReaderThread();
if ( !QIODevice::atEnd() ) {
- qDebug( "KDPipeIODevice::atEnd returns false since QIODevice::atEnd does (with bytesAvailable=%ld)", static_cast<long>(bytesAvailable()) );
+ qDebug( "%p: KDPipeIODevice::atEnd returns false since QIODevice::atEnd does (with bytesAvailable=%ld)", this, static_cast<long>(bytesAvailable()) );
return false;
}
if ( !isOpen() )
@@ -361,14 +399,15 @@
const bool eof = ( d->reader->error || d->reader->eof ) && d->reader->bufferEmpty();
if ( !eof ) {
if ( !d->reader->error && !d->reader->eof )
- qDebug( "KDPipeIODevice::atEnd returns false since !reader->error && !reader->eof" );
+ qDebug( "%p: KDPipeIODevice::atEnd returns false since !reader->error && !reader->eof", this );
if ( !d->reader->bufferEmpty() )
- qDebug( "KDPipeIODevice::atEnd returns false since !reader->bufferEmpty()" );
+ qDebug( "%p: KDPipeIODevice::atEnd returns false since !reader->bufferEmpty()", this );
}
return eof;
}
bool KDPipeIODevice::waitForBytesWritten( int msecs ) { KDAB_CHECK_THIS;
+ d->startWriterThread();
Writer * const w = d->writer;
if ( !w )
return true;
@@ -377,6 +416,7 @@
}
bool KDPipeIODevice::waitForReadyRead( int msecs ) { KDAB_CHECK_THIS;
+ d->startReaderThread();
if ( ALLOW_QIODEVICE_BUFFERING ) {
if ( bytesAvailable() > 0 )
return true;
@@ -389,18 +429,22 @@
}
qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS;
+ qDebug( "%p: KDPipeIODevice::readData: data=%p, maxSize=%lld", this, data, maxSize );
- qDebug( "KDPipeIODevice::readData: data=%p, maxSize=%lld", data, maxSize );
+ if ( maxSize == 0 )
+ return 0;
+ d->startReaderThread();
Reader * const r = d->reader;
assert( r );
+
//assert( r->isRunning() ); // wrong (might be eof, error)
assert( data || maxSize == 0 );
assert( maxSize >= 0 );
if ( r->eofShortCut ) {
- qDebug( "KDPipeIODevice::readData: hit eofShortCut, returning 0" );
+ qDebug( "%p: KDPipeIODevice::readData: hit eofShortCut, returning 0", this );
return 0;
}
@@ -414,31 +458,31 @@
LOCKED( r );
if ( /* maxSize > 0 && */ r->bufferEmpty() && !r->error && !r->eof ) { // ### block on maxSize == 0?
- qDebug( "KDPipeIODevice::readData: waiting for bufferNotEmptyCondition" );
+ qDebug( "%p: KDPipeIODevice::readData: waiting for bufferNotEmptyCondition", this );
r->bufferNotEmptyCondition.wait( &r->mutex );
}
if ( r->bufferEmpty() ) {
- qDebug( "KDPipeIODevice::readData: got empty buffer, signal eof" );
+ qDebug( "%p: KDPipeIODevice::readData: got empty buffer, signal eof", this );
// woken with an empty buffer must mean either EOF or error:
assert( r->eof || r->error );
r->eofShortCut = true;
return r->eof ? 0 : -1 ;
}
- qDebug( "KDPipeIODevice::readData: got bufferNotEmptyCondition, trying to read %lld bytes", maxSize );
+ qDebug( "%p: KDPipeIODevice::readData: got bufferNotEmptyCondition, trying to read %lld bytes", this, maxSize );
const qint64 bytesRead = r->readData( data, maxSize );
- qDebug( "KDPipeIODevice::readData: read %lld bytes", bytesRead );
+ qDebug( "%p: KDPipeIODevice::readData: read %lld bytes", this, bytesRead );
+ qDebug( "%p (fd=%d): KDPipeIODevice::readData: %s", this, d->fd, data );
return bytesRead;
}
qint64 Reader::readData( char * data, qint64 maxSize ) {
-
qint64 numRead = rptr < wptr ? wptr - rptr : sizeof buffer - rptr ;
if ( numRead > maxSize )
numRead = maxSize;
- qDebug( "KDPipeIODevice::readData: data=%p, maxSize=%lld; rptr=%u, wptr=%u (bytesInBuffer=%u); -> numRead=%lld",
+ qDebug( "%p: KDPipeIODevice::readData: data=%p, maxSize=%lld; rptr=%u, wptr=%u (bytesInBuffer=%u); -> numRead=%lld", this,
data, maxSize, rptr, wptr, bytesInBuffer(), numRead );
std::memcpy( data, buffer + rptr, numRead );
@@ -446,7 +490,7 @@
rptr = ( rptr + numRead ) % sizeof buffer ;
if ( !bufferFull() ) {
- qDebug( "KDPipeIODevice::readData: signal bufferNotFullCondition" );
+ qDebug( "%p: KDPipeIODevice::readData: signal bufferNotFullCondition", this );
bufferNotFullCondition.wakeAll();
}
@@ -454,7 +498,7 @@
}
qint64 KDPipeIODevice::writeData( const char * data, qint64 size ) { KDAB_CHECK_THIS;
-
+ d->startWriterThread();
Writer * const w = d->writer;
assert( w );
@@ -476,7 +520,6 @@
}
qint64 Writer::writeData( const char * data, qint64 size ) {
-
assert( bufferEmpty() );
if ( size > static_cast<qint64>( sizeof buffer ) )
@@ -492,40 +535,47 @@
return size;
}
-void KDPipeIODevice::close() { KDAB_CHECK_THIS;
+void KDPipeIODevice::Private::stopThreads()
+{
+ if ( triedToStartWriter )
+ {
+ if ( writer && q->bytesToWrite() > 0 )
+ q->waitForBytesWritten( -1 );
- if ( !isOpen() )
- return;
-
- // tell clients we're about to close:
- emit aboutToClose();
-
- if ( d->writer && bytesToWrite() > 0 )
- waitForBytesWritten( -1 );
-
- assert( bytesToWrite() == 0 );
-
- if ( Reader * & r = d->reader ) {
+ assert( q->bytesToWrite() == 0 );
+ }
+ if ( Reader * & r = reader ) {
synchronized( r ) {
// tell thread to cancel:
r->cancel = true;
// and wake it, so it can terminate:
r->bufferNotFullCondition.wakeAll();
}
- r->wait();
- delete r; r = 0;
}
- if ( Writer * & w = d->writer ) {
+ if ( Writer * & w = writer ) {
synchronized( w ) {
// tell thread to cancel:
w->cancel = true;
// and wake it, so it can terminate:
w->bufferNotEmptyCondition.wakeAll();
}
- w->wait();
- delete w; w = 0;
}
+}
+void KDPipeIODevice::close() { KDAB_CHECK_THIS;
+
+ if ( !isOpen() )
+ return;
+
+ // tell clients we're about to close:
+ emit aboutToClose();
+ d->stopThreads();
+
+#define waitAndDelete( t ) if ( t ) { t->wait(); delete t; t = 0; }
+ waitAndDelete( d->writer );
+ waitAndDelete( d->reader );
+#undef waitAndDelete
+
#ifdef Q_OS_WIN32
CloseHandle( d->handle );
#else
@@ -544,19 +594,19 @@
// too bad QThread doesn't have that itself; a signal isn't enough
hasStarted.wakeAll();
- qDebug( "Reader::run: started" );
+ qDebug( "%p: Reader::run: started", this );
while ( true ) {
while ( !cancel && bufferFull() ) {
bufferNotEmptyCondition.wakeAll();
- qDebug( "Reader::run: buffer is full, going to sleep" );
+ qDebug( "%p: Reader::run: buffer is full, going to sleep", this );
bufferNotFullCondition.wait( &mutex );
- qDebug( "Reader::run: woke up" );
+ qDebug( "%p: Reader::run: woke up", this );
}
if ( cancel ) {
- qDebug( "Reader::run: detected cancel" );
+ qDebug( "%p: Reader::run: detected cancel", this );
goto leave;
}
@@ -567,11 +617,11 @@
if ( numBytes > sizeof buffer - wptr )
numBytes = sizeof buffer - wptr;
- qDebug( "Reader::run: rptr=%d, wptr=%d -> numBytes=%d", rptr, wptr, numBytes );
+ qDebug( "%p: Reader::run: rptr=%d, wptr=%d -> numBytes=%d", this, rptr, wptr, numBytes );
assert( numBytes > 0 );
- qDebug( "Reader::run: trying to read %d bytes", numBytes );
+ qDebug( "%p: Reader::run: trying to read %d bytes", this, numBytes );
#ifdef Q_OS_WIN32
DWORD numRead;
mutex.unlock();
@@ -580,10 +630,10 @@
if ( !ok ) {
errorCode = static_cast<int>( GetLastError() );
if ( errorCode == ERROR_BROKEN_PIPE ) {
- qDebug( "Reader::run: got eof" );
+ qDebug( "%p: Reader::run: got eof (broken pipe)", this );
eof = true;
} else {
- qDebug( "Reader::run: got error: %d", errorCode );
+ qDebug( "%p: Reader::run: got error: %s (%d)", this, strerror( errorCode ), errorCode );
error = true;
}
goto leave;
@@ -599,32 +649,33 @@
if ( numRead < 0 ) {
errorCode = errno;
error = true;
- qDebug( "Reader::run: got error: %d", errorCode );
+ qDebug( "%p: Reader::run: got error: %d", this, errorCode );
goto leave;
}
#endif
- qDebug( "Reader::run: read %ld bytes", static_cast<long>(numRead) );
+ qDebug( "%p: Reader::run: read %ld bytes", this, static_cast<long>(numRead) );
+ qDebug( "%p (fd=%d): KDPipeIODevice::readData: %s", this, fd, buffer );
if ( numRead == 0 ) {
- qDebug( "Reader::run: eof detected" );
+ qDebug( "%p: Reader::run: eof detected", this );
eof = true;
goto leave;
}
if ( cancel ) {
- qDebug( "Reader::run: detected cancel" );
+ qDebug( "%p: Reader::run: detected cancel", this );
goto leave;
}
- qDebug( "Reader::run: buffer before: rptr=%4d, wptr=%4d", rptr, wptr );
+ qDebug( "%p: Reader::run: buffer before: rptr=%4d, wptr=%4d", this, rptr, wptr );
wptr = ( wptr + numRead ) % sizeof buffer;
- qDebug( "Reader::run: buffer after: rptr=%4d, wptr=%4d", rptr, wptr );
+ qDebug( "%p: Reader::run: buffer after: rptr=%4d, wptr=%4d", this, rptr, wptr );
if ( !bufferEmpty() ) {
- qDebug( "Reader::run: buffer no longer empty, waking everyone" );
+ qDebug( "%p: Reader::run: buffer no longer empty, waking everyone", this );
bufferNotEmptyCondition.wakeAll();
emit readyRead();
}
}
leave:
- qDebug( "Reader::run: terminating" );
+ qDebug( "%p: Reader::run: terminating", this );
bufferNotEmptyCondition.wakeAll();
emit readyRead();
}
@@ -636,25 +687,25 @@
// too bad QThread doesn't have that itself; a signal isn't enough
hasStarted.wakeAll();
- qDebug( "Writer::run: started" );
+ qDebug( "%p: Writer::run: started", this );
while ( true ) {
while ( !cancel && bufferEmpty() ) {
bufferEmptyCondition.wakeAll();
- qDebug( "Writer::run: buffer is empty, going to sleep" );
+ qDebug( "%p: Writer::run: buffer is empty, going to sleep", this );
bufferNotEmptyCondition.wait( &mutex );
- qDebug( "Writer::run: woke up" );
+ qDebug( "%p: Writer::run: woke up", this );
}
if ( cancel ) {
- qDebug( "Writer::run: detected cancel" );
+ qDebug( "%p: Writer::run: detected cancel", this );
goto leave;
}
assert( numBytesInBuffer > 0 );
- qDebug( "Writer::run: Trying to write %u bytes", numBytesInBuffer );
+ qDebug( "%p: Writer::run: Trying to write %u bytes", this, numBytesInBuffer );
qint64 totalWritten = 0;
do {
mutex.unlock();
@@ -663,7 +714,7 @@
if ( !WriteFile( handle, buffer + totalWritten, numBytesInBuffer - totalWritten, &numWritten, 0 ) ) {
mutex.lock();
errorCode = static_cast<int>( GetLastError() );
- qDebug( "Writer::run: got error code: %d", errorCode );
+ qDebug( "%p: Writer::run: got error code: %d", this, errorCode );
error = true;
goto leave;
}
@@ -676,7 +727,7 @@
if ( numWritten < 0 ) {
mutex.lock();
errorCode = errno;
- qDebug( "Writer::run: got error code: %d", errorCode );
+ qDebug( "%p: Writer::run: got error code: %d", this, errorCode );
error = true;
goto leave;
}
@@ -685,14 +736,14 @@
mutex.lock();
} while ( totalWritten < numBytesInBuffer );
- qDebug( "Writer::run: wrote %lld bytes", totalWritten );
+ qDebug( "%p: Writer::run: wrote %lld bytes", this, totalWritten );
numBytesInBuffer = 0;
bufferEmptyCondition.wakeAll();
emit bytesWritten( totalWritten );
}
leave:
- qDebug( "Writer::run: terminating" );
+ qDebug( "%p: Writer::run: terminating", this );
numBytesInBuffer = 0;
bufferEmptyCondition.wakeAll();
emit bytesWritten( 0 );
Modified: trunk/gpgme/kdpipeiodevice.moc
===================================================================
--- trunk/gpgme/kdpipeiodevice.moc 2007-09-27 13:01:54 UTC (rev 1266)
+++ trunk/gpgme/kdpipeiodevice.moc 2007-09-27 22:21:10 UTC (rev 1267)
@@ -1,8 +1,8 @@
/****************************************************************************
** Meta object code from reading C++ file 'kdpipeiodevice.cpp'
**
-** Created: Mon Aug 27 15:17:18 2007
-** by: The Qt Meta Object Compiler version 59 (Qt 4.3.0)
+** Created: Wed Sep 26 11:05:05 2007
+** by: The Qt Meta Object Compiler version 59 (Qt 4.3.1)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
@@ -10,7 +10,7 @@
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'kdpipeiodevice.cpp' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 59
-#error "This file was generated using the moc from 4.3.0. It"
+#error "This file was generated using the moc from 4.3.1. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
@@ -130,3 +130,45 @@
void *_a[] = { 0, const_cast<void*>(reinterpret_cast<const void*>(&_t1)) };
QMetaObject::activate(this, &staticMetaObject, 0, _a);
}
+static const uint qt_meta_data_KDPipeIODevice__Private[] = {
+
+ // content:
+ 1, // revision
+ 0, // classname
+ 0, 0, // classinfo
+ 0, 0, // methods
+ 0, 0, // properties
+ 0, 0, // enums/sets
+
+ 0 // eod
+};
+
+static const char qt_meta_stringdata_KDPipeIODevice__Private[] = {
+ "KDPipeIODevice::Private\0"
+};
+
+const QMetaObject KDPipeIODevice::Private::staticMetaObject = {
+ { &QObject::staticMetaObject, qt_meta_stringdata_KDPipeIODevice__Private,
+ qt_meta_data_KDPipeIODevice__Private, 0 }
+};
+
+const QMetaObject *KDPipeIODevice::Private::metaObject() const
+{
+ return &staticMetaObject;
+}
+
+void *KDPipeIODevice::Private::qt_metacast(const char *_clname)
+{
+ if (!_clname) return 0;
+ if (!strcmp(_clname, qt_meta_stringdata_KDPipeIODevice__Private))
+ return static_cast<void*>(const_cast< Private*>(this));
+ return QObject::qt_metacast(_clname);
+}
+
+int KDPipeIODevice::Private::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+ _id = QObject::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ return _id;
+}
Modified: trunk/gpgme/w32-qt-io.cpp
===================================================================
--- trunk/gpgme/w32-qt-io.cpp 2007-09-27 13:01:54 UTC (rev 1266)
+++ trunk/gpgme/w32-qt-io.cpp 2007-09-27 22:21:10 UTC (rev 1267)
@@ -82,12 +82,20 @@
really nice callback interfaces to let the user control all this at
a per-context level. */
-
-#define MAX_SLAFD 256
+#define MAX_SLAFD 50000
-QIODevice *iodevice_table[MAX_SLAFD];
+struct DeviceEntry {
+ DeviceEntry() : iodev( 0 ), actual_fd( -1 ), refCount( 1 ) {}
+ QIODevice* iodev;
+ int actual_fd;
+ mutable int refCount;
+ void ref() const { ++refCount; }
+ int unref() const { return --refCount; }
+};
+DeviceEntry* iodevice_table[MAX_SLAFD];
+
static QIODevice *
find_channel (int fd, int create)
{
@@ -95,13 +103,16 @@
return NULL;
if (create && !iodevice_table[fd])
- iodevice_table[fd] = new KDPipeIODevice
- (fd, QIODevice::ReadOnly|QIODevice::Unbuffered);
-
- return iodevice_table[fd];
+ {
+ DeviceEntry* entry = new DeviceEntry;
+ entry->actual_fd = fd;
+ entry->iodev = new KDPipeIODevice
+ (fd, QIODevice::ReadWrite|QIODevice::Unbuffered);
+ iodevice_table[fd] = entry;
+ }
+ return iodevice_table[fd] ? iodevice_table[fd]->iodev : 0;
}
-
/* Write the printable version of FD to the buffer BUF of length
BUFLEN. The printable version is the representation on the command
line that the child process expects. */
@@ -232,7 +243,9 @@
/* Now we have a pipe with the right end inheritable. The other end
should have a giochannel. */
+
chan = find_channel (filedes[1 - inherit_idx], 1);
+
if (!chan)
{
int saved_errno = errno;
@@ -248,7 +261,6 @@
chan);
}
-
int
_gpgme_io_close (int fd)
{
@@ -270,16 +282,29 @@
}
/* Then do the close. */
- chan = iodevice_table[fd];
- if (chan)
- {
- chan->close();
- delete chan;
- iodevice_table[fd] = NULL;
+
+ DeviceEntry* const entry = iodevice_table[fd];
+ if ( entry )
+ {
+ assert( entry->refCount > 0 );
+ const int actual_fd = entry->actual_fd;
+ assert( actual_fd > 0 );
+ if ( !entry->unref() ) {
+ entry->iodev->close();
+ delete entry->iodev;
+ delete entry;
+ for ( int i = 0; i < MAX_SLAFD; ++i ) {
+ if ( iodevice_table[i] == entry )
+ iodevice_table[i] = 0;
+ }
}
+
+ if ( fd != actual_fd )
+ _close( fd );
+ }
else
_close (fd);
-
+
return 0;
}
@@ -334,7 +359,7 @@
/* The leading double-quote. */
n++;
while (*p)
- {
+ {
/* An extra one for each literal that must be escaped. */
if (*p == '\\' || *p == '"')
n++;
@@ -586,13 +611,6 @@
}
-int
-_gpgme_io_dup (int fd)
-{
- return _dup (fd);
-}
-
-
/* Look up the qiodevice for file descriptor FD. */
extern "C"
void *
@@ -610,3 +628,16 @@
return NULL;
}
+
+int
+_gpgme_io_dup (int fd)
+{
+ const int new_fd = _dup( fd );
+ iodevice_table[new_fd] = iodevice_table[fd];
+ if ( iodevice_table[new_fd] )
+ iodevice_table[new_fd]->ref();
+ else
+ find_channel( new_fd, /*create=*/1 );
+ return new_fd;
+}
+
More information about the Gnupg-commits
mailing list