diff options
Diffstat (limited to '')
| -rw-r--r-- | configure.ac | 16 | ||||
| -rw-r--r-- | src/Makefile.am | 33 | ||||
| -rw-r--r-- | src/kdpipeiodevice.cpp | 951 | ||||
| -rw-r--r-- | src/kdpipeiodevice.h | 73 | ||||
| -rw-r--r-- | src/kdpipeiodevice.moc | 183 | ||||
| -rw-r--r-- | src/w32-qt-io.cpp | 700 | 
6 files changed, 4 insertions, 1952 deletions
| diff --git a/configure.ac b/configure.ac index 5aad9f40..c3a46ae7 100644 --- a/configure.ac +++ b/configure.ac @@ -180,20 +180,9 @@ case "${host}" in  	AC_ARG_ENABLE(w32-glib,  	    AC_HELP_STRING([--enable-w32-glib], [build GPGME Glib for W32]),  	    		   build_w32_glib=$enableval) - -	# Check disabled, because the qt-dev packages in gpg4win do -	# not provide any support for cross compilation. -	# PKG_CHECK_MODULES(QT4_CORE, QtCore) - -	# Use it like this: -	# ./configure --enable-w32-qt QT4_CORE_CFLAGS="..." QT4_CORE_LIBS="..." -	AC_SUBST(QT4_CORE_CFLAGS) -	AC_SUBST(QT4_CORE_LIBS) -	AC_ARG_ENABLE(w32-qt, -	    AC_HELP_STRING([--enable-w32-qt], [build GPGME Qt for W32]), -	    		   build_w32_qt=$enableval) -        ;; +       ;;      *) +  	AC_CHECK_LIB(pthread,pthread_create,have_pthread=yes)  	if test "$have_pthread" = yes; then  	  AC_DEFINE(HAVE_PTHREAD, ,[Define if we have pthread.]) @@ -239,7 +228,6 @@ fi  AM_CONDITIONAL(HAVE_ANDROID_SYSTEM, test "$have_android_system" = yes)  AM_CONDITIONAL(BUILD_W32_GLIB, test "$build_w32_glib" = yes) -AM_CONDITIONAL(BUILD_W32_QT, test "$build_w32_qt" = yes)  AM_CONDITIONAL(HAVE_PTHREAD, test "$have_pthread" = "yes") diff --git a/src/Makefile.am b/src/Makefile.am index 698c6322..951fc00b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,12 +41,6 @@ else  ltlib_gpgme_glib =  endif -if BUILD_W32_QT -ltlib_gpgme_qt = libgpgme-qt.la -else -ltlib_gpgme_qt = -endif -  lib_LTLIBRARIES = libgpgme.la $(ltlib_gpgme_glib) $(ltlib_gpgme_qt) \  	$(ltlib_gpgme_pthread) @@ -110,23 +104,9 @@ if BUILD_W32_GLIB  libgpgme_glib_la_SOURCES = $(main_sources) ath.h ath.c w32-glib-io.c  endif -if BUILD_W32_QT -libgpgme_qt_la_SOURCES = $(main_sources) ath.h ath.c w32-qt-io.cpp \ -	kdpipeiodevice.h kdpipeiodevice.cpp kdpipeiodevice.moc -# FIXME: Add extra depedency: moc_kdpipeiodevice.cpp - -# These are built sources (normally). -# moc_kdpipeiodevice.cpp: kdpipeiodevice.h -#	$(MOC4) -o $@ $< -# -# kdpipeiodevice.moc: kdpipeiodevice.cpp -#	$(MOC4) -o $@ $< -endif - -# We use a global CFLAGS and CPPFLAGS setting for all library +# We use a global CFLAGS setting for all library  # versions, because then every object file is only compiled once. -AM_CPPFLAGS = @GPG_ERROR_CFLAGS@ @QT4_CORE_CFLAGS@ -AM_CFLAGS = @LIBASSUAN_CFLAGS@ @GLIB_CFLAGS@ @QT4_CORE_CFLAGS@ +AM_CFLAGS = @LIBASSUAN_CFLAGS@ @GLIB_CFLAGS@  gpgme_tool_SOURCES = gpgme-tool.c argparse.c argparse.h  gpgme_tool_LDADD = libgpgme.la @LIBASSUAN_LIBS@ @@ -202,15 +182,6 @@ libgpgme_glib_la_LIBADD = $(gpgme_res) @LIBASSUAN_LIBS@ @LTLIBOBJS@ \  	@GPG_ERROR_LIBS@ @GLIB_LIBS@  endif -if BUILD_W32_QT -libgpgme_qt_la_LDFLAGS = $(no_undefined) \ -	$(export_symbols) $(libgpgme_version_script_cmd) -version-info \ -	@LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@ -libgpgme_qt_la_DEPENDENCIES = @LTLIBOBJS@ $(srcdir)/libgpgme.vers $(gpgme_deps) -libgpgme_qt_la_LIBADD = $(gpgme_res) @LIBASSUAN_LIBS@ @LTLIBOBJS@ \ -	@GPG_ERROR_LIBS@ @QT4_CORE_LIBS@ -endif -  install-data-local: install-def-file  uninstall-local: uninstall-def-file diff --git a/src/kdpipeiodevice.cpp b/src/kdpipeiodevice.cpp deleted file mode 100644 index 5661790a..00000000 --- a/src/kdpipeiodevice.cpp +++ /dev/null @@ -1,951 +0,0 @@ -/* -  Copyright (C) 2007 Klar�lvdalens Datakonsult AB - -  KDPipeIODevice is free software; you can redistribute it and/or -  modify it under the terms of the GNU Library General Public -  License as published by the Free Software Foundation; either -  version 2 of the License, or (at your option) any later version. - -  KDPipeIODevice is distributed in the hope that it will be useful, -  but WITHOUT ANY WARRANTY; without even the implied warranty of -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -  GNU Library General Public License for more details. - -  You should have received a copy of the GNU Library General Public License -  along with KDPipeIODevice; see the file COPYING.LIB.  If not, write to the -  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -  Boston, MA 02110-1301, USA. -*/ - -#include "kdpipeiodevice.h" - -#include <QtCore> - -#include <cassert> -#include <memory> -#include <algorithm> - -#ifdef Q_OS_WIN32 -# ifndef NOMINMAX -#  define NOMINMAX -# endif -# include <windows.h> -# include <io.h> -#else -# include <unistd.h> -# include <errno.h> -#endif - -using namespace _gpgme_; - -#ifndef KDAB_CHECK_THIS -# define KDAB_CHECK_CTOR (void)1 -# define KDAB_CHECK_DTOR KDAB_CHECK_CTOR -# define KDAB_CHECK_THIS KDAB_CHECK_CTOR -#endif - -#define LOCKED( d ) const QMutexLocker locker( &d->mutex ) -#define synchronized( d ) if ( int i = 0 ) {} else for ( const QMutexLocker locker( &d->mutex ) ; !i ; ++i ) - -const unsigned int BUFFER_SIZE = 4096; -const bool ALLOW_QIODEVICE_BUFFERING = true; - -// comment to get trace output: -//#define qDebug if(1){}else qDebug - -namespace { -class Reader : public QThread { -    Q_OBJECT -public: -    Reader( int fd, Qt::HANDLE handle ); -    ~Reader(); - -    qint64 readData( char * data, qint64 maxSize ); - -    unsigned int bytesInBuffer() const { -        return ( wptr + sizeof buffer - rptr ) % sizeof buffer ; -    } - -    bool bufferFull() const { -        return bytesInBuffer() == sizeof buffer - 1; -    } - -    bool bufferEmpty() const { -	return bytesInBuffer() == 0; -    } - -    bool bufferContains( char ch ) { -	const unsigned int bib = bytesInBuffer(); -	for ( unsigned int i = rptr ; i < rptr + bib ; ++i ) -	    if ( buffer[i%sizeof buffer] == ch ) -		return true; -	return false; -    } -         -    void notifyReadyRead(); - -Q_SIGNALS: -    void readyRead(); - -protected: -    /* reimp */ void run(); - -private: -    int fd; -    Qt::HANDLE handle; -public: -    QMutex mutex; -    QWaitCondition waitForCancelCondition; -    QWaitCondition bufferNotFullCondition; -    QWaitCondition bufferNotEmptyCondition; -    QWaitCondition hasStarted; -    QWaitCondition readyReadSentCondition; -    QWaitCondition blockedConsumerIsDoneCondition; -    bool cancel; -    bool eof; -    bool error; -    bool eofShortCut; -    int errorCode; -    bool isReading; -    bool consumerBlocksOnUs; -    -private: -    unsigned int rptr, wptr; -    char buffer[BUFFER_SIZE+1]; // need to keep one byte free to detect empty state -}; - - -Reader::Reader( int fd_, Qt::HANDLE handle_ ) -    : QThread(), -      fd( fd_ ), -      handle( handle_ ), -      mutex(), -      bufferNotFullCondition(), -      bufferNotEmptyCondition(), -      hasStarted(), -      cancel( false ), -      eof( false ), -      error( false ), -      eofShortCut( false ), -      errorCode( 0 ), -      isReading( false ), -      consumerBlocksOnUs( false ), -      rptr( 0 ), wptr( 0 ) -{ -     -} - -Reader::~Reader() {} - - -class Writer : public QThread { -    Q_OBJECT -public: -    Writer( int fd, Qt::HANDLE handle ); -    ~Writer(); - -    qint64 writeData( const char * data, qint64 size ); - -    unsigned int bytesInBuffer() const { return numBytesInBuffer; } - -    bool bufferFull() const { -        return numBytesInBuffer == sizeof buffer; -    } - -    bool bufferEmpty() const { -	return numBytesInBuffer == 0; -    } - -Q_SIGNALS: -    void bytesWritten( qint64 ); - -protected: -    /* reimp */ void run(); - -private: -    int fd; -    Qt::HANDLE handle; -public: -    QMutex mutex; -    QWaitCondition bufferEmptyCondition; -    QWaitCondition bufferNotEmptyCondition; -    QWaitCondition hasStarted; -    bool cancel; -    bool error; -    int errorCode; -private: -    unsigned int numBytesInBuffer; -    char buffer[BUFFER_SIZE]; -}; -} - -Writer::Writer( int fd_, Qt::HANDLE handle_ ) -    : QThread(), -      fd( fd_ ), -      handle( handle_ ), -      mutex(), -      bufferEmptyCondition(), -      bufferNotEmptyCondition(), -      hasStarted(), -      cancel( false ), -      error( false ), -      errorCode( 0 ), -      numBytesInBuffer( 0 ) -{ - -} - -Writer::~Writer() {} - - -class KDPipeIODevice::Private : public QObject { -Q_OBJECT -    friend class ::KDPipeIODevice; -    KDPipeIODevice * const q; -public: -    explicit Private( KDPipeIODevice * qq ); -    ~Private(); - -    bool doOpen( int, Qt::HANDLE, OpenMode ); -    bool startReaderThread();  -    bool startWriterThread();  -    void stopThreads(); - -public Q_SLOTS: -    void emitReadyRead(); -  -private: -    int fd; -    Qt::HANDLE handle; -    Reader * reader; -    Writer * writer; -    bool triedToStartReader; -    bool triedToStartWriter; -}; - -KDPipeIODevice::Private::Private( KDPipeIODevice * qq ) -    : QObject( qq ), q( qq ), -      fd( -1 ), -      handle( 0 ), -      reader( 0 ), -      writer( 0 ), -      triedToStartReader( false ), triedToStartWriter( false )  -{ - -} - -KDPipeIODevice::Private::~Private() { -    qDebug( "KDPipeIODevice::~Private(): Destroying %p", q ); -} - -KDPipeIODevice::KDPipeIODevice( QObject * p ) -    : QIODevice( p ), d( new Private( this ) ) -{ -    KDAB_CHECK_CTOR; -} - -KDPipeIODevice::KDPipeIODevice( int fd, OpenMode mode, QObject * p ) -    : QIODevice( p ), d( new Private( this ) ) -{ -    KDAB_CHECK_CTOR; -    open( fd, mode ); -} - -KDPipeIODevice::KDPipeIODevice( Qt::HANDLE handle, OpenMode mode, QObject * p ) -    : QIODevice( p ), d( new Private( this ) ) -{ -    KDAB_CHECK_CTOR; -    open( handle, mode ); -} - -KDPipeIODevice::~KDPipeIODevice() { KDAB_CHECK_DTOR; -    if ( isOpen() ) -	close(); -    delete d; d = 0; -} - - -bool KDPipeIODevice::open( int fd, OpenMode mode ) { KDAB_CHECK_THIS; - -#ifdef Q_OS_WIN32 -    return d->doOpen( fd, (HANDLE)_get_osfhandle( fd ), mode ); -#else -    return d->doOpen( fd, 0, mode ); -#endif - -} - -bool KDPipeIODevice::open( Qt::HANDLE h, OpenMode mode ) { KDAB_CHECK_THIS; - -#ifdef Q_OS_WIN32 -    return d->doOpen( -1, h, mode ); -#else -    Q_UNUSED( h ); -    Q_UNUSED( mode ); -    assert( !"KDPipeIODevice::open( Qt::HANDLE, OpenMode ) should never be called except on Windows." ); -#endif - -} - -bool KDPipeIODevice::Private::startReaderThread() -{ -   if ( triedToStartReader ) -       return true; -   triedToStartReader = true;     -   if ( reader && !reader->isRunning() && !reader->isFinished() ) { -       qDebug("KDPipeIODevice::Private::startReaderThread(): locking reader (CONSUMER THREAD)" ); -       LOCKED( reader ); -       qDebug("KDPipeIODevice::Private::startReaderThread(): locked reader (CONSUMER THREAD)" ); -       reader->start( QThread::HighestPriority ); -       qDebug("KDPipeIODevice::Private::startReaderThread(): waiting for hasStarted (CONSUMER THREAD)" ); -       const bool hasStarted = reader->hasStarted.wait( &reader->mutex, 1000 ); -       qDebug("KDPipeIODevice::Private::startReaderThread(): returned from hasStarted (CONSUMER THREAD)" ); - -       return hasStarted; -   } -   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; -} - -void KDPipeIODevice::Private::emitReadyRead() -{ -    QPointer<Private> thisPointer( this ); -    qDebug( "KDPipeIODevice::Private::emitReadyRead %p", this ); - -    emit q->readyRead(); - -    if ( !thisPointer ) -        return; - -    bool mustNotify = false; - -    if ( reader ) { -        qDebug( "KDPipeIODevice::Private::emitReadyRead %p: locking reader (CONSUMER THREAD)", this ); -        synchronized( reader ) { -            qDebug( "KDPipeIODevice::Private::emitReadyRead %p: locked reader (CONSUMER THREAD)", this ); -            reader->readyReadSentCondition.wakeAll(); -            mustNotify = !reader->bufferEmpty() && reader->isReading; -            qDebug( "KDPipeIODevice::emitReadyRead %p: bufferEmpty: %d reader in ReadFile: %d", this, reader->bufferEmpty(), reader->isReading ); -        } -    } -    if ( mustNotify ) -        QTimer::singleShot( 100, this, SLOT( emitReadyRead() ) );   -    qDebug( "KDPipeIODevice::Private::emitReadyRead %p leaving", this ); - -} - -bool KDPipeIODevice::Private::doOpen( int fd_, Qt::HANDLE handle_, OpenMode mode_ ) { - -    if ( q->isOpen() ) -	return false; - -#ifdef Q_OS_WIN32 -    if ( !handle_ ) -	return false; -#else -    if ( fd_ < 0 ) -	return false; -#endif - -    if ( !(mode_ & ReadWrite) ) -	return false; // need to have at least read -or- write - - -    std::auto_ptr<Reader> reader_; -    std::auto_ptr<Writer> writer_; - -    if ( mode_ & ReadOnly ) { -	reader_.reset( new Reader( fd_, handle_ ) ); -        qDebug( "KDPipeIODevice::doOpen (%p): created reader (%p) for fd %d", this, reader_.get(), fd_ );  -	connect( reader_.get(), SIGNAL(readyRead()), this, SLOT(emitReadyRead()),  -Qt::QueuedConnection ); -    } -    if ( mode_ & WriteOnly ) { -	writer_.reset( new Writer( fd_, handle_ ) ); -        qDebug( "KDPipeIODevice::doOpen (%p): created writer (%p) for fd %d", this, writer_.get(), fd_ );  -        connect( writer_.get(), SIGNAL(bytesWritten(qint64)), q, SIGNAL(bytesWritten(qint64)),  -Qt::QueuedConnection ); -    } - -    // commit to *this: -    fd = fd_; -    handle = handle_; -    reader = reader_.release(); -    writer = writer_.release(); - -    q->setOpenMode( mode_|Unbuffered ); -    return true; -} - -int KDPipeIODevice::descriptor() const { KDAB_CHECK_THIS; -    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 ) { -            const qint64 inBuffer = d->reader->bytesInBuffer();      -            return base + inBuffer; -       } -    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(); -    return base; -} - -bool KDPipeIODevice::canReadLine() const { KDAB_CHECK_THIS; -    d->startReaderThread(); -   if ( QIODevice::canReadLine() ) -	return true; -    if ( d->reader ) -	synchronized( d->reader ) return d->reader->bufferContains( '\n' ); -    return true; -} - -bool KDPipeIODevice::isSequential() const { -    return true; -} - -bool KDPipeIODevice::atEnd() const { KDAB_CHECK_THIS; -    d->startReaderThread(); -    if ( !QIODevice::atEnd() ) { -	qDebug( "%p: KDPipeIODevice::atEnd returns false since QIODevice::atEnd does (with bytesAvailable=%ld)", this, static_cast<long>(bytesAvailable()) ); -	return false; -    } -    if ( !isOpen() ) -	return true; -    if ( d->reader->eofShortCut ) -	return true; -    LOCKED( d->reader ); -    const bool eof = ( d->reader->error || d->reader->eof ) && d->reader->bufferEmpty(); -    if ( !eof ) { -	if ( !d->reader->error && !d->reader->eof ) -	    qDebug( "%p: KDPipeIODevice::atEnd returns false since !reader->error && !reader->eof", this ); -	if ( !d->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; -    LOCKED( w ); -    qDebug( "KDPipeIODevice::waitForBytesWritten (%p,w=%p): entered locked area", this, w  -);  -    return w->bufferEmpty() || w->error || w->bufferEmptyCondition.wait( &w->mutex, msecs ) ; -} - -bool KDPipeIODevice::waitForReadyRead( int msecs ) { KDAB_CHECK_THIS; -    qDebug( "KDPipeIODEvice::waitForReadyRead()(%p)", this); -    d->startReaderThread(); -    if ( ALLOW_QIODEVICE_BUFFERING ) { -	if ( bytesAvailable() > 0 ) -	    return true; -    } -    Reader * const r = d->reader; -    if ( !r || r->eofShortCut ) -	return true; -    LOCKED( r ); -    if ( r->bytesInBuffer() != 0 || r->eof || r->error ) -        return true; - -    return msecs >= 0 ? r->bufferNotEmptyCondition.wait( &r->mutex, msecs ) : r->bufferNotEmptyCondition.wait( &r->mutex ); -} - -template <typename T> -class TemporaryValue { -public: -   TemporaryValue( T& var_, const T& tv ) : var( var_ ), oldValue( var_ ) { var = tv; } -   ~TemporaryValue() { var = oldValue; } -private:    -   T& var; -   const T oldValue; -};  - - -bool KDPipeIODevice::readWouldBlock() const -{ -   d->startReaderThread(); -   LOCKED( d->reader ); -   return d->reader->bufferEmpty() && !d->reader->eof && !d->reader->error; -}   - -bool KDPipeIODevice::writeWouldBlock() const -{ -   d->startWriterThread(); -   LOCKED( d->writer ); -   return !d->writer->bufferEmpty() && !d->writer->error; -}   - - -qint64 KDPipeIODevice::readData( char * data, qint64 maxSize ) { KDAB_CHECK_THIS; -    qDebug( "%p: KDPipeIODevice::readData: data=%p, maxSize=%lld", this, data, maxSize ); -    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( "%p: KDPipeIODevice::readData: hit eofShortCut, returning 0", this ); -	return 0; -    } - -    if ( maxSize < 0 ) -	maxSize = 0; - -    if ( ALLOW_QIODEVICE_BUFFERING ) { -	if ( bytesAvailable() > 0 ) -	    maxSize = std::min( maxSize, bytesAvailable() ); // don't block -    } -    qDebug( "%p: KDPipeIODevice::readData: try to lock reader (CONSUMER THREAD)", this ); -    LOCKED( r ); -    qDebug( "%p: KDPipeIODevice::readData: locked reader (CONSUMER THREAD)", this ); - -    r->readyReadSentCondition.wakeAll(); -    if ( /* maxSize > 0 && */ r->bufferEmpty() &&  !r->error && !r->eof ) { // ### block on maxSize == 0? -	qDebug( "%p: KDPipeIODevice::readData: waiting for bufferNotEmptyCondition (CONSUMER THREAD)", this ); -        const TemporaryValue<bool> tmp( d->reader->consumerBlocksOnUs, true ); -	r->bufferNotEmptyCondition.wait( &r->mutex ); -        r->blockedConsumerIsDoneCondition.wakeAll(); -	qDebug( "%p: KDPipeIODevice::readData: woke up from bufferNotEmptyCondition (CONSUMER THREAD)", this );  -    } - -    if ( r->bufferEmpty() ) { -	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( "%p: KDPipeIODevice::readData: got bufferNotEmptyCondition, trying to read %lld bytes", this, maxSize ); -    const qint64 bytesRead = r->readData( data, maxSize ); -    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( "%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 ); - -    rptr = ( rptr + numRead ) % sizeof buffer ; - -    if ( !bufferFull() ) { -	qDebug( "%p: KDPipeIODevice::readData: signal bufferNotFullCondition", this ); -	bufferNotFullCondition.wakeAll(); -    } - -    return numRead; -} - -qint64 KDPipeIODevice::writeData( const char * data, qint64 size ) { KDAB_CHECK_THIS; -    d->startWriterThread(); -    Writer * const w = d->writer; - -    assert( w ); -    assert( w->error || w->isRunning() ); -    assert( data || size == 0 ); -    assert( size >= 0 ); - -    LOCKED( w ); - -    while ( !w->error && !w->bufferEmpty() ) {  -	qDebug( "%p: KDPipeIODevice::writeData: wait for empty buffer", this ); -	w->bufferEmptyCondition.wait( &w->mutex ); -	qDebug( "%p: KDPipeIODevice::writeData: empty buffer signaled", this ); - -    } -    if ( w->error ) -	return -1; - -    assert( w->bufferEmpty() ); - -    return w->writeData( data, size ); -} - -qint64 Writer::writeData( const char * data, qint64 size ) { -    assert( bufferEmpty() ); - -    if ( size > static_cast<qint64>( sizeof buffer ) ) -	size = sizeof buffer; - -    std::memcpy( buffer, data, size ); -     -    numBytesInBuffer = size; - -    if ( !bufferEmpty() ) { -	bufferNotEmptyCondition.wakeAll(); -    } -   return size; -} - -void KDPipeIODevice::Private::stopThreads() -{ -    if ( triedToStartWriter ) -    { -        if ( writer && q->bytesToWrite() > 0 ) -	    q->waitForBytesWritten( -1 ); - -        assert( q->bytesToWrite() == 0 ); -    } -    if ( Reader * & r = reader ) { -        disconnect( r, SIGNAL( readyRead() ), this, SLOT( emitReadyRead() ) );  -	synchronized( r ) { -	    // tell thread to cancel: -	    r->cancel = true; -	    // and wake it, so it can terminate: -            r->waitForCancelCondition.wakeAll(); -	    r->bufferNotFullCondition.wakeAll(); -            r->readyReadSentCondition.wakeAll(); -      	} -    } -    if ( Writer * & w = writer ) { -	synchronized( w ) { -	    // tell thread to cancel: -	    w->cancel = true; -	    // and wake it, so it can terminate: -	    w->bufferNotEmptyCondition.wakeAll(); -	} -    } -} - -void KDPipeIODevice::close() { KDAB_CHECK_THIS; -    qDebug( "KDPipeIODevice::close(%p)", this ); -    if ( !isOpen() ) -	return; - -    // tell clients we're about to close: -    emit aboutToClose(); -    d->stopThreads(); - -#define waitAndDelete( t ) if ( t ) { t->wait(); QThread* const t2 = t; t = 0; delete t2; } -    qDebug( "KPipeIODevice::close(%p): wait and closing writer %p", this, d->writer ); -    waitAndDelete( d->writer ); -    qDebug( "KPipeIODevice::close(%p): wait and closing reader %p", this, d->reader ); -    if ( d->reader ) { -        LOCKED( d->reader ); -        d->reader->readyReadSentCondition.wakeAll(); -    } -    waitAndDelete( d->reader ); -#undef waitAndDelete -#ifdef Q_OS_WIN32 -    if ( d->fd != -1 ) -        _close( d->fd ); -    else -        CloseHandle( d->handle ); -#else -    ::close( d->fd ); -#endif - -    setOpenMode( NotOpen ); -    d->fd = -1; -    d->handle = 0; -} - -void Reader::run() { - -    LOCKED( this ); - -    // too bad QThread doesn't have that itself; a signal isn't enough -    hasStarted.wakeAll(); - -    qDebug( "%p: Reader::run: started", this ); - -    while ( true ) { -        if ( !cancel && ( eof || error ) ) { -            //notify the client until the buffer is empty and then once  -            //again so he receives eof/error. After that, wait for him  -            //to cancel  -            const bool wasEmpty = bufferEmpty(); -	    qDebug( "%p: Reader::run: received eof(%d) or error(%d), waking everyone", this, eof, error ); -            notifyReadyRead(); -            if ( !cancel && wasEmpty )  -                waitForCancelCondition.wait( &mutex ); -        } else if ( !cancel && !bufferFull() && !bufferEmpty() ) { -	    qDebug( "%p: Reader::run: buffer no longer empty, waking everyone", this ); -            notifyReadyRead(); -        }  -  -        while ( !cancel && !error && bufferFull() ) { -            notifyReadyRead(); -            if ( !cancel && bufferFull() ) { -                qDebug( "%p: Reader::run: buffer is full, going to sleep", this ); -	        bufferNotFullCondition.wait( &mutex ); -	    } -        } -         -	if ( cancel ) { -            qDebug( "%p: Reader::run: detected cancel", this ); -	    goto leave; -	} - -        if ( !eof && !error ) { -            if ( rptr == wptr ) // optimize for larger chunks in case the buffer is empty -	        rptr = wptr = 0; - -            unsigned int numBytes = ( rptr + sizeof buffer - wptr - 1 ) % sizeof buffer; -	    if ( numBytes > sizeof buffer - wptr ) -	        numBytes = sizeof buffer - wptr; - -	    qDebug( "%p: Reader::run: rptr=%d, wptr=%d -> numBytes=%d", this, rptr, wptr, numBytes ); - -	    assert( numBytes > 0 ); - -	    qDebug( "%p: Reader::run: trying to read %d bytes", this, numBytes ); -#ifdef Q_OS_WIN32 -            isReading = true; -	    mutex.unlock(); -            DWORD numRead; -	    const bool ok = ReadFile( handle, buffer + wptr, numBytes, &numRead, 0 ); -	    mutex.lock(); -            isReading = false; -	    if ( ok ) { -                if ( numRead == 0 ) { -                    qDebug( "%p: Reader::run: got eof (numRead==0)", this ); -                    eof = true; -                }  -            } else { // !ok -	        errorCode = static_cast<int>( GetLastError() ); -	        if ( errorCode == ERROR_BROKEN_PIPE ) { -                    assert( numRead == 0 ); -                    qDebug( "%p: Reader::run: got eof (broken pipe)", this ); -		    eof = true; -	        } else { -                    assert( numRead == 0 ); -		    qDebug( "%p: Reader::run: got error: %s (%d)", this, strerror( errorCode ), errorCode ); -		    error = true; -	        } -	    } -#else -	    qint64 numRead; -	    mutex.unlock(); -	    do { -	        numRead = ::read( fd, buffer + wptr, numBytes ); -	    } while ( numRead == -1 && errno == EINTR ); -	    mutex.lock(); - -	    if ( numRead < 0 ) { -	        errorCode = errno; -	        error = true; -	        qDebug( "%p: Reader::run: got error: %d", this, errorCode ); -            } else if ( numRead == 0 ) { -	        qDebug( "%p: Reader::run: eof detected", this );   -                eof = true; -            } -#endif -	    qDebug( "%p: Reader::run: read %ld bytes", this, static_cast<long>(numRead) ); -	    qDebug( "%p: Reader::run(fd=%d): %s", this, fd, buffer ); - -	    if ( numRead > 0 ) { -	        qDebug( "%p: Reader::run: buffer before: rptr=%4d, wptr=%4d", this, rptr, wptr ); -	        wptr = ( wptr + numRead ) % sizeof buffer; -	        qDebug( "%p: Reader::run: buffer after:  rptr=%4d, wptr=%4d", this, rptr, wptr ); -            } -        } -    } - leave: -    qDebug( "%p: Reader::run: terminated", this ); -} - -void Reader::notifyReadyRead() -{ -    qDebug( "notifyReadyRead: %d bytes available", bytesInBuffer() ); -    assert( !cancel ); - -    if ( consumerBlocksOnUs ) { -        bufferNotEmptyCondition.wakeAll(); -        blockedConsumerIsDoneCondition.wait( &mutex ); -        return; -    } -    qDebug( "notifyReadyRead: emit signal" ); -    emit readyRead(); -    readyReadSentCondition.wait( &mutex ); -    qDebug( "notifyReadyRead: returning from waiting, leave" ); -} - -void Writer::run() { - -    LOCKED( this ); - -    // too bad QThread doesn't have that itself; a signal isn't enough -    hasStarted.wakeAll(); - -    qDebug( "%p: Writer::run: started", this ); - -    while ( true ) { - -	while ( !cancel && bufferEmpty() ) { -	    qDebug( "%p: Writer::run: buffer is empty, wake bufferEmptyCond listeners", this ); -            bufferEmptyCondition.wakeAll(); -            emit bytesWritten( 0 ); -	    qDebug( "%p: Writer::run: buffer is empty, going to sleep", this ); -            bufferNotEmptyCondition.wait( &mutex ); -	    qDebug( "%p: Writer::run: woke up", this ); -	} - -	if ( cancel ) { -	    qDebug( "%p: Writer::run: detected cancel", this ); -	    goto leave; -	} - -	assert( numBytesInBuffer > 0 ); - -	qDebug( "%p: Writer::run: Trying to write %u bytes", this, numBytesInBuffer ); -	qint64 totalWritten = 0; -	do {   -            mutex.unlock(); -#ifdef Q_OS_WIN32 -            DWORD numWritten; -            qDebug( "%p (fd=%d): Writer::run: buffer before WriteFile (numBytes=%lld): %s:", this, fd, numBytesInBuffer, buffer );  -            qDebug( "%p (fd=%d): Writer::run: Going into WriteFile", this, fd ); -	    if ( !WriteFile( handle, buffer + totalWritten, numBytesInBuffer - totalWritten, &numWritten, 0 ) ) { -		mutex.lock(); -		errorCode = static_cast<int>( GetLastError() ); -		qDebug( "%p: Writer::run: got error code: %d", this, errorCode ); -		error = true; -                goto leave; -	    } -#else -	    qint64 numWritten; -	    do { -		numWritten = ::write( fd, buffer + totalWritten, numBytesInBuffer - totalWritten ); -	    } while ( numWritten == -1 && errno == EINTR ); - -	    if ( numWritten < 0 ) { -	        mutex.lock(); -		errorCode = errno; -		qDebug( "%p: Writer::run: got error code: %d", this, errorCode ); -		error = true; -                goto leave; -	    } -#endif -            qDebug( "%p (fd=%d): Writer::run: buffer after WriteFile (numBytes=%u): %s:", this, fd, numBytesInBuffer, buffer ); -	    totalWritten += numWritten; -            mutex.lock(); -	} while ( totalWritten < numBytesInBuffer ); - -	qDebug( "%p: Writer::run: wrote %lld bytes", this, totalWritten ); - -	numBytesInBuffer = 0; - -	qDebug( "%p: Writer::run: buffer is empty, wake bufferEmptyCond listeners", this ); -	bufferEmptyCondition.wakeAll(); -	emit bytesWritten( totalWritten ); -    } - leave: -    qDebug( "%p: Writer::run: terminating", this ); -    numBytesInBuffer = 0; -    qDebug( "%p: Writer::run: buffer is empty, wake bufferEmptyCond listeners", this ); -    bufferEmptyCondition.wakeAll(); -    emit bytesWritten( 0 ); -} - -// static  -std::pair<KDPipeIODevice*,KDPipeIODevice*> KDPipeIODevice::makePairOfConnectedPipes() { -    KDPipeIODevice * read = 0; -    KDPipeIODevice * write = 0; -#ifdef Q_OS_WIN32 -    HANDLE rh; -    HANDLE wh; -    SECURITY_ATTRIBUTES sa; -    memset( &sa, 0, sizeof(sa) ); -    sa.nLength = sizeof(sa); -    sa.bInheritHandle = TRUE; -	if ( CreatePipe( &rh, &wh, &sa, BUFFER_SIZE ) ) { -	read = new KDPipeIODevice; -	read->open( rh, ReadOnly ); -	write = new KDPipeIODevice; -	write->open( wh, WriteOnly ); -    } -#else -    int fds[2]; -    if ( pipe( fds ) == 0 ) { -	read = new KDPipeIODevice; -	read->open( fds[0], ReadOnly ); -	write = new KDPipeIODevice; -	write->open( fds[1], WriteOnly ); -    } -#endif -    return std::make_pair( read, write ); -} - -#ifdef KDAB_DEFINE_CHECKS -KDAB_DEFINE_CHECKS( KDPipeIODevice ) { -    if ( !isOpen() ) { -	assert( openMode() == NotOpen ); -	assert( !d->reader ); -	assert( !d->writer ); -#ifdef Q_OS_WIN32 -	assert( !d->handle ); -#else -	assert( d->fd < 0 ); -#endif -    } else { -	assert( openMode() != NotOpen ); -	assert( openMode() & ReadWrite ); -	if ( openMode() & ReadOnly ) { -	    assert( d->reader ); -	    synchronized( d->reader ) -		assert( d->reader->eof || d->reader->error || d->reader->isRunning() ); -	} -	if ( openMode() & WriteOnly ) { -	    assert( d->writer ); -	    synchronized( d->writer ) -		assert( d->writer->error || d->writer->isRunning() ); -	} -#ifdef Q_OS_WIN32 -	assert( d->handle ); -#else -	assert( d->fd >= 0 ); -#endif -    } -} -#endif // KDAB_DEFINE_CHECKS - -#include "moc_kdpipeiodevice.cpp" -#include "kdpipeiodevice.moc" diff --git a/src/kdpipeiodevice.h b/src/kdpipeiodevice.h deleted file mode 100644 index 8da6af68..00000000 --- a/src/kdpipeiodevice.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -  Copyright (C) 2007 Klar�lvdalens Datakonsult AB - -  KDPipeIODevice is free software; you can redistribute it and/or -  modify it under the terms of the GNU Library General Public -  License as published by the Free Software Foundation; either -  version 2 of the License, or (at your option) any later version. - -  KDPipeIODevice is distributed in the hope that it will be useful, -  but WITHOUT ANY WARRANTY; without even the implied warranty of -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -  GNU Library General Public License for more details. - -  You should have received a copy of the GNU Library General Public License -  along with KDPipeIODevice; see the file COPYING.LIB.  If not, write to the -  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -  Boston, MA 02110-1301, USA. -*/ - -#ifndef __KDTOOLSCORE_KDPIPEIODEVICE_H__ -#define __KDTOOLSCORE_KDPIPEIODEVICE_H__ - -#include <QIODevice> - -#include <utility> - -//#include "checker.h" - -namespace _gpgme_ { - -class KDPipeIODevice : public QIODevice { -    Q_OBJECT -    //KDAB_MAKE_CHECKABLE( KDPipeIODevice ) -public: -    explicit KDPipeIODevice( QObject * parent=0 ); -    explicit KDPipeIODevice( int fd, OpenMode=ReadOnly, QObject * parent=0 ); -    explicit KDPipeIODevice( Qt::HANDLE handle, OpenMode=ReadOnly, QObject * parent=0 ); -    ~KDPipeIODevice(); - -    static std::pair<KDPipeIODevice*, KDPipeIODevice*> makePairOfConnectedPipes(); - -    bool open( int fd, OpenMode mode=ReadOnly ); -    bool open( Qt::HANDLE handle, OpenMode mode=ReadOnly ); - -    Qt::HANDLE handle() const; -    int descriptor() const; - -    bool readWouldBlock() const; -    bool writeWouldBlock() const; - -    /* reimp */ qint64 bytesAvailable() const; -    /* reimp */ qint64 bytesToWrite() const; -    /* reimp */ bool canReadLine() const; -    /* reimp */ void close(); -    /* reimp */ bool isSequential() const; -    /* reimp */ bool atEnd() const; - -    /* reimp */ bool waitForBytesWritten( int msecs ); -    /* reimp */ bool waitForReadyRead( int msecs ); - -protected: -    /* reimp */ qint64 readData( char * data, qint64 maxSize ); -    /* reimp */ qint64 writeData( const char * data, qint64 maxSize ); - -private: -    class Private; -    Private * d; -}; - -} /* namespace _gpgme_ */ - -#endif /* __KDTOOLSCORE_KDPIPEIODEVICE_H__ */ - diff --git a/src/kdpipeiodevice.moc b/src/kdpipeiodevice.moc deleted file mode 100644 index 457f371a..00000000 --- a/src/kdpipeiodevice.moc +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** Meta object code from reading C++ file 'kdpipeiodevice.cpp' -** -** Created: Tue Oct 2 19:30:13 2007 -**      by: The Qt Meta Object Compiler version 59 (Qt 4.3.1) -** -** WARNING! All changes made in this file will be lost! -*****************************************************************************/ - -#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.1. It" -#error "cannot be used with the include files from this version of Qt." -#error "(The moc has changed too much.)" -#endif - -static const uint qt_meta_data_Reader[] = { - - // content: -       1,       // revision -       0,       // classname -       0,    0, // classinfo -       1,   10, // methods -       0,    0, // properties -       0,    0, // enums/sets - - // signals: signature, parameters, type, tag, flags -       8,    7,    7,    7, 0x05, - -       0        // eod -}; - -static const char qt_meta_stringdata_Reader[] = { -    "Reader\0\0readyRead()\0" -}; - -const QMetaObject Reader::staticMetaObject = { -    { &QThread::staticMetaObject, qt_meta_stringdata_Reader, -      qt_meta_data_Reader, 0 } -}; - -const QMetaObject *Reader::metaObject() const -{ -    return &staticMetaObject; -} - -void *Reader::qt_metacast(const char *_clname) -{ -    if (!_clname) return 0; -    if (!strcmp(_clname, qt_meta_stringdata_Reader)) -	return static_cast<void*>(const_cast< Reader*>(this)); -    return QThread::qt_metacast(_clname); -} - -int Reader::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ -    _id = QThread::qt_metacall(_c, _id, _a); -    if (_id < 0) -        return _id; -    if (_c == QMetaObject::InvokeMetaMethod) { -        switch (_id) { -        case 0: readyRead(); break; -        } -        _id -= 1; -    } -    return _id; -} - -// SIGNAL 0 -void Reader::readyRead() -{ -    QMetaObject::activate(this, &staticMetaObject, 0, 0); -} -static const uint qt_meta_data_Writer[] = { - - // content: -       1,       // revision -       0,       // classname -       0,    0, // classinfo -       1,   10, // methods -       0,    0, // properties -       0,    0, // enums/sets - - // signals: signature, parameters, type, tag, flags -       8,    7,    7,    7, 0x05, - -       0        // eod -}; - -static const char qt_meta_stringdata_Writer[] = { -    "Writer\0\0bytesWritten(qint64)\0" -}; - -const QMetaObject Writer::staticMetaObject = { -    { &QThread::staticMetaObject, qt_meta_stringdata_Writer, -      qt_meta_data_Writer, 0 } -}; - -const QMetaObject *Writer::metaObject() const -{ -    return &staticMetaObject; -} - -void *Writer::qt_metacast(const char *_clname) -{ -    if (!_clname) return 0; -    if (!strcmp(_clname, qt_meta_stringdata_Writer)) -	return static_cast<void*>(const_cast< Writer*>(this)); -    return QThread::qt_metacast(_clname); -} - -int Writer::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -{ -    _id = QThread::qt_metacall(_c, _id, _a); -    if (_id < 0) -        return _id; -    if (_c == QMetaObject::InvokeMetaMethod) { -        switch (_id) { -        case 0: bytesWritten((*reinterpret_cast< qint64(*)>(_a[1]))); break; -        } -        _id -= 1; -    } -    return _id; -} - -// SIGNAL 0 -void Writer::bytesWritten(qint64 _t1) -{ -    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 -       1,   10, // methods -       0,    0, // properties -       0,    0, // enums/sets - - // slots: signature, parameters, type, tag, flags -      25,   24,   24,   24, 0x0a, - -       0        // eod -}; - -static const char qt_meta_stringdata_KDPipeIODevice__Private[] = { -    "KDPipeIODevice::Private\0\0emitReadyRead()\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; -    if (_c == QMetaObject::InvokeMetaMethod) { -        switch (_id) { -        case 0: emitReadyRead(); break; -        } -        _id -= 1; -    } -    return _id; -} diff --git a/src/w32-qt-io.cpp b/src/w32-qt-io.cpp deleted file mode 100644 index 44655ecb..00000000 --- a/src/w32-qt-io.cpp +++ /dev/null @@ -1,700 +0,0 @@ -/* w32-qt-io.c - W32 Glib I/O functions -   Copyright (C) 2000 Werner Koch (dd9jn) -   Copyright (C) 2001, 2002, 2004, 2005, 2007 g10 Code GmbH - -   This file is part of GPGME. - -   GPGME is free software; you can redistribute it and/or modify it -   under the terms of the GNU Lesser General Public License as -   published by the Free Software Foundation; either version 2.1 of -   the License, or (at your option) any later version. - -   GPGME is distributed in the hope that it will be useful, but -   WITHOUT ANY WARRANTY; without even the implied warranty of -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU -   Lesser General Public License for more details. - -   You should have received a copy of the GNU Lesser General Public -   License along with this program; if not, write to the Free Software -   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -   02111-1307, USA.  */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/time.h> -#include <sys/types.h> -#include <windows.h> -#include <io.h> - -#include "kdpipeiodevice.h" - -extern "C" -{ -#include "util.h" -#include "priv-io.h" -#include "sema.h" -#include "debug.h" -} - -#ifndef O_BINARY -#ifdef _O_BINARY -#define O_BINARY	_O_BINARY -#else -#define O_BINARY	0 -#endif -#endif - -using _gpgme_::KDPipeIODevice; - - -/* This file is an ugly hack to get GPGME working with Qt on Windows -   targets.  On Windows, you can not select() on file descriptors. - -   The only way to check if there is something to read is to read -   something.  This means that GPGME can not let Qt check for data -   without letting Qt also handle the data on Windows targets. - -   The ugly consequence is that we need to work on QIODevices in -   GPGME, creating a Qt dependency.  Also, we need to export an -   interface for the application to get at GPGME's QIODevices.  There -   is no good way to abstract all this with callbacks, because the -   whole thing is also interconnected with the creation of pipes and -   child processes. - -   The following rule applies only to this I/O backend: - -   * ALL operations must use the user defined event loop.  GPGME can -   not anymore provide its own event loop.  This is mostly a sanity -   requirement: Although we have in theory all information we need to -   make the GPGME W32 code for select still work, it would be a big -   complication and require changes throughout GPGME. - -   Eventually, we probably have to bite the bullet and make some -   really nice callback interfaces to let the user control all this at -   a per-context level.  */ - -#define MAX_SLAFD 1024 - -struct DeviceEntry { -  DeviceEntry() : iodev( 0 ), refCount( 1 ), blocking( true ) {} -    KDPipeIODevice* iodev; -    bool blocking; -    mutable int refCount; -    void ref() const { ++refCount; } -    int unref() const { assert( refCount > 0 ); return --refCount; } -}; - -DeviceEntry* iodevice_table[MAX_SLAFD]; - - -static KDPipeIODevice * -find_channel (int fd, int create) -{ -  assert( fd < MAX_SLAFD ); -  if (fd < 0 || fd >= MAX_SLAFD) -    return NULL; - -  if (create && !iodevice_table[fd]) -  { -    DeviceEntry* entry = new DeviceEntry; -    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.  */ -int -_gpgme_io_fd2str (char *buf, int buflen, int fd) -{ -  return snprintf (buf, buflen, "%d", (long)_get_osfhandle( fd ) ); -} - - -void -_gpgme_io_subsystem_init (void) -{ -} - - -static struct -{ -  _gpgme_close_notify_handler_t handler; -  void *value; -} notify_table[MAX_SLAFD]; - - -int -_gpgme_io_read (int fd, void *buffer, size_t count) -{ -  int saved_errno = 0; -  qint64 nread; -  KDPipeIODevice *chan; -  TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_read", fd, -	      "buffer=%p, count=%u", buffer, count); - -  chan = find_channel (fd, 0); -  if (!chan) -    { -      TRACE_LOG ("no channel registered"); -      errno = EINVAL; -      return TRACE_SYSRES (-1); -    } -  TRACE_LOG1 ("channel %p", chan); -  if ( iodevice_table[fd] && !iodevice_table[fd]->blocking && chan->readWouldBlock() ) { -      errno = EAGAIN; -      return TRACE_SYSRES( -1 ); -  } - -  nread = chan->read ((char *) buffer, count); -  if (nread < 0) -    { -      TRACE_LOG1 ("err %s", qPrintable (chan->errorString ())); -      saved_errno = EIO; -      nread = -1; -    } - -  TRACE_LOGBUF ((char *) buffer, nread); - -  errno = saved_errno; -  return TRACE_SYSRES (nread); -} - - -int -_gpgme_io_write (int fd, const void *buffer, size_t count) -{ -  qint64 nwritten; -  KDPipeIODevice *chan; -  TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_write", fd, -	      "buffer=%p, count=%u", buffer, count); -  TRACE_LOGBUF ((char *) buffer, count); - -  chan = find_channel (fd, 0); -  if (!chan) -    { -      TRACE_LOG ("fd %d: no channel registered"); -      errno = EINVAL; -      return -1; -    } - -  if ( iodevice_table[fd] && !iodevice_table[fd]->blocking && chan->writeWouldBlock() ) -  { -      errno = EAGAIN; -      return TRACE_SYSRES( -1 ); -  } -  nwritten = chan->write ((char *) buffer, count); - -  if (nwritten < 0) -    { -      nwritten = -1; -      errno = EIO; -      return TRACE_SYSRES(-1); -    } -  errno = 0; -  return TRACE_SYSRES (nwritten); -} - - -int -_gpgme_io_pipe (int filedes[2], int inherit_idx) -{ -  KDPipeIODevice *chan; -  TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_pipe", filedes, -	      "inherit_idx=%i (GPGME uses it for %s)", -	      inherit_idx, inherit_idx ? "reading" : "writing"); - -#define PIPEBUF_SIZE  4096 -  if (_pipe (filedes, PIPEBUF_SIZE, O_NOINHERIT | O_BINARY) == -1) -    return TRACE_SYSRES (-1); - -  /* Make one end inheritable. */ -  if (inherit_idx == 0) -    { -      int new_read; - -      new_read = _dup (filedes[0]); -      _close (filedes[0]); -      filedes[0] = new_read; - -      if (new_read < 0) -	{ -	  _close (filedes[1]); -	  return TRACE_SYSRES (-1); -	} -    } -  else if (inherit_idx == 1) -    { -      int new_write; - -      new_write = _dup (filedes[1]); -      _close (filedes[1]); -      filedes[1] = new_write; - -      if (new_write < 0) -	{ -	  _close (filedes[0]); -	  return TRACE_SYSRES (-1); -	} -    } - -  /* 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; -      _close (filedes[0]); -      _close (filedes[1]); -      errno = saved_errno; -      return TRACE_SYSRES (-1); -    } - -  return TRACE_SUC5 ("read=0x%x/%p, write=0x%x/%p, channel=%p", -	  filedes[0], (HANDLE) _get_osfhandle (filedes[0]), -	  filedes[1], (HANDLE) _get_osfhandle (filedes[1]), -	  chan); -} - -int -_gpgme_io_close (int fd) -{ -  KDPipeIODevice *chan; -  TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd); - -  if (fd < 0 || fd >= MAX_SLAFD) -    { -      errno = EBADF; -      return TRACE_SYSRES (-1); -    } - -  /* First call the notify handler.  */ -  if (notify_table[fd].handler) -    { -      notify_table[fd].handler (fd, notify_table[fd].value); -      notify_table[fd].handler = NULL; -      notify_table[fd].value = NULL; -    } - -  /* Then do the close.  */ - -  DeviceEntry* const entry = iodevice_table[fd]; -  if ( entry ) { -      if ( entry->unref() == 0 ) { -          entry->iodev->close(); -          delete entry->iodev; -          delete entry; -          iodevice_table[fd] = 0; -      } -  } else { -      _close( fd ); -  } - - - -  return 0; -} - - -int -_gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler, -			    void *value) -{ -  TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_set_close_notify", fd, -	      "close_handler=%p/%p", handler, value); - -  assert (fd != -1); - -  if (fd < 0 || fd >= (int) DIM (notify_table)) -    { -      errno = EINVAL; -      return TRACE_SYSRES (-1); -    } -  notify_table[fd].handler = handler; -  notify_table[fd].value = value; -  return TRACE_SYSRES (0); -} - - -int -_gpgme_io_set_nonblocking (int fd) -{ -  DeviceEntry* const entry = iodevice_table[fd]; -  assert( entry ); -  entry->blocking = false; -  TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_set_nonblocking", fd); -  return TRACE_SYSRES (0); -} - - -static char * -build_commandline (char **argv) -{ -  int i; -  int n = 0; -  char *buf; -  char *p; - -  /* We have to quote some things because under Windows the program -     parses the commandline and does some unquoting.  We enclose the -     whole argument in double-quotes, and escape literal double-quotes -     as well as backslashes with a backslash.  We end up with a -     trailing space at the end of the line, but that is harmless.  */ -  for (i = 0; argv[i]; i++) -    { -      p = argv[i]; -      /* The leading double-quote.  */ -      n++; -      while (*p) -      { -	  /* An extra one for each literal that must be escaped.  */ -	  if (*p == '\\' || *p == '"') -	    n++; -	  n++; -	  p++; -	} -      /* The trailing double-quote and the delimiter.  */ -      n += 2; -    } -  /* And a trailing zero.  */ -  n++; - -  buf = p = (char *) malloc (n); -  if (!buf) -    return NULL; -  for (i = 0; argv[i]; i++) -    { -      char *argvp = argv[i]; - -      *(p++) = '"'; -      while (*argvp) -	{ -	  if (*argvp == '\\' || *argvp == '"') -	    *(p++) = '\\'; -	  *(p++) = *(argvp++); -	} -      *(p++) = '"'; -      *(p++) = ' '; -    } -  *(p++) = 0; - -  return buf; -} - - -int -_gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags, -		 struct spawn_fd_item_s *fd_list, -		 void (*atfork) (void *opaque, int reserved), -		 void *atforkvalue, pid_t *r_pid) -{ -  SECURITY_ATTRIBUTES sec_attr; -  PROCESS_INFORMATION pi = -    { -      NULL,      /* returns process handle */ -      0,         /* returns primary thread handle */ -      0,         /* returns pid */ -      0         /* returns tid */ -    }; -  STARTUPINFO si; -  int cr_flags = CREATE_DEFAULT_ERROR_MODE -    | GetPriorityClass (GetCurrentProcess ()); -  int i; -  char **args; -  char *arg_string; -  /* FIXME.  */ -  int debug_me = 0; -  int tmp_fd; -  char *tmp_name; - -  TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_spawn", path, -	      "path=%s", path); -  i = 0; -  while (argv[i]) -    { -      TRACE_LOG2 ("argv[%2i] = %s", i, argv[i]); -      i++; -    } - -  /* We do not inherit any handles by default, and just insert those -     handles we want the child to have afterwards.  But some handle -     values occur on the command line, and we need to move -     stdin/out/err to the right location.  So we use a wrapper program -     which gets the information from a temporary file.  */ -  if (_gpgme_mkstemp (&tmp_fd, &tmp_name) < 0) -    { -      TRACE_LOG1 ("_gpgme_mkstemp failed: %s", strerror (errno)); -      return TRACE_SYSRES (-1); -    } -  TRACE_LOG1 ("tmp_name = %s", tmp_name); - -  args = (char **) calloc (2 + i + 1, sizeof (*args)); -  args[0] = (char *) _gpgme_get_w32spawn_path (); -  args[1] = tmp_name; -  args[2] = const_cast<char *>(path); -  memcpy (&args[3], &argv[1], i * sizeof (*args)); - -  memset (&sec_attr, 0, sizeof sec_attr); -  sec_attr.nLength = sizeof sec_attr; -  sec_attr.bInheritHandle = FALSE; - -  arg_string = build_commandline (args); -  free (args); -  if (!arg_string) -    { -      close (tmp_fd); -      DeleteFile (tmp_name); -      return TRACE_SYSRES (-1); -    } - -  memset (&si, 0, sizeof si); -  si.cb = sizeof (si); -  si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; -  si.wShowWindow = debug_me ? SW_SHOW : SW_HIDE; -  si.hStdInput = INVALID_HANDLE_VALUE; -  si.hStdOutput = INVALID_HANDLE_VALUE; -  si.hStdError = INVALID_HANDLE_VALUE; - -  cr_flags |= CREATE_SUSPENDED; -  if ((flags & IOSPAWN_FLAG_DETACHED)) -    cr_flags |= DETACHED_PROCESS; -  if (!CreateProcessA (_gpgme_get_w32spawn_path (), -		       arg_string, -		       &sec_attr,     /* process security attributes */ -		       &sec_attr,     /* thread security attributes */ -		       FALSE,         /* inherit handles */ -		       cr_flags,      /* creation flags */ -		       NULL,          /* environment */ -		       NULL,          /* use current drive/directory */ -		       &si,           /* startup information */ -		       &pi))          /* returns process information */ -    { -      TRACE_LOG1 ("CreateProcess failed: ec=%d", (int) GetLastError ()); -      free (arg_string); -      close (tmp_fd); -      DeleteFile (tmp_name); - -      /* FIXME: Should translate the error code.  */ -      errno = EIO; -      return TRACE_SYSRES (-1); -    } - -  free (arg_string); - -  if (flags & IOSPAWN_FLAG_ALLOW_SET_FG) -    _gpgme_allow_set_foreground_window ((pid_t)pi.dwProcessId); - -  /* Insert the inherited handles.  */ -  for (i = 0; fd_list[i].fd != -1; i++) -    { -      HANDLE hd; - -      if (!DuplicateHandle (GetCurrentProcess(), -			    (HANDLE) _get_osfhandle (fd_list[i].fd), -			    pi.hProcess, &hd, 0, TRUE, DUPLICATE_SAME_ACCESS)) -	{ -	  TRACE_LOG1 ("DuplicateHandle failed: ec=%d", (int) GetLastError ()); -	  TerminateProcess (pi.hProcess, 0); -	  /* Just in case TerminateProcess didn't work, let the -	     process fail on its own.  */ -	  ResumeThread (pi.hThread); -	  CloseHandle (pi.hThread); -	  CloseHandle (pi.hProcess); - -	  close (tmp_fd); -	  DeleteFile (tmp_name); - -	  /* FIXME: Should translate the error code.  */ -	  errno = EIO; -	  return TRACE_SYSRES (-1); -        } -      /* Return the child name of this handle.  */ -      fd_list[i].peer_name = (int) hd; -    } - -  /* Write the handle translation information to the temporary -     file.  */ -  { -    /* Hold roughly MAX_TRANS quadruplets of 64 bit numbers in hex -       notation: "0xFEDCBA9876543210" with an extra white space after -       every quadruplet.  10*(19*4 + 1) - 1 = 769.  This plans ahead -       for a time when a HANDLE is 64 bit.  */ -#define BUFFER_MAX 800 -    char line[BUFFER_MAX + 1]; -    int res; -    int written; -    size_t len; - -    if ((flags & IOSPAWN_FLAG_ALLOW_SET_FG)) -      strcpy (line, "~1 \n"); -    else -      strcpy (line, "\n"); -    for (i = 0; fd_list[i].fd != -1; i++) -      { -	/* Strip the newline.  */ -	len = strlen (line) - 1; - -	/* Format is: Local name, stdin/stdout/stderr, peer name, argv idx.  */ -	snprintf (&line[len], BUFFER_MAX - len, "0x%x %d 0x%x %d  \n", -		  fd_list[i].fd, fd_list[i].dup_to, -		  fd_list[i].peer_name, fd_list[i].arg_loc); -	/* Rather safe than sorry.  */ -	line[BUFFER_MAX - 1] = '\n'; -	line[BUFFER_MAX] = '\0'; -      } -    len = strlen (line); -    written = 0; -    do -      { -	res = write (tmp_fd, &line[written], len - written); -	if (res > 0) -	  written += res; -      } -    while (res > 0 || (res < 0 && errno == EAGAIN)); -  } -  close (tmp_fd); -  /* The temporary file is deleted by the gpgme-w32spawn process -     (hopefully).  */ - -  TRACE_LOG4 ("CreateProcess ready: hProcess=%p, hThread=%p, " -	      "dwProcessID=%d, dwThreadId=%d", -	      pi.hProcess, pi.hThread, -	      (int) pi.dwProcessId, (int) pi.dwThreadId); - -  if (r_pid) -    *r_pid = (pid_t)pi.dwProcessId; - -  if (ResumeThread (pi.hThread) < 0) -    TRACE_LOG1 ("ResumeThread failed: ec=%d", (int) GetLastError ()); - -  if (!CloseHandle (pi.hThread)) -    TRACE_LOG1 ("CloseHandle of thread failed: ec=%d", -		(int) GetLastError ()); - -  TRACE_LOG1 ("process=%p", pi.hProcess); - -  /* We don't need to wait for the process.  */ -  if (!CloseHandle (pi.hProcess)) -    TRACE_LOG1 ("CloseHandle of process failed: ec=%d", -		(int) GetLastError ()); - -  for (i = 0; fd_list[i].fd != -1; i++) -    _gpgme_io_close (fd_list[i].fd); - -  for (i = 0; fd_list[i].fd != -1; i++) -    if (fd_list[i].dup_to == -1) -      TRACE_LOG3 ("fd[%i] = 0x%x -> 0x%x", i, fd_list[i].fd, -		  fd_list[i].peer_name); -    else -      TRACE_LOG4 ("fd[%i] = 0x%x -> 0x%x (std%s)", i, fd_list[i].fd, -		  fd_list[i].peer_name, (fd_list[i].dup_to == 0) ? "in" : -		  ((fd_list[i].dup_to == 1) ? "out" : "err")); - -  return TRACE_SYSRES (0); -} - - -/* Select on the list of fds.  Returns: -1 = error, 0 = timeout or -   nothing to select, > 0 = number of signaled fds.  */ -int -_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock) -{ -  /* Use a 1s timeout.  */ - -  void *dbg_help = NULL; -  TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_select", fds, -	      "nfds=%u, nonblock=%u", nfds, nonblock); - -  int count = 0; - -  TRACE_SEQ (dbg_help, "select on [ "); -  for (int i = 0; i < nfds; i++) -    { -      if (fds[i].fd == -1) -        { -          fds[i].signaled = 0; -	} -      else if (fds[i].for_read ) -      { -          KDPipeIODevice * const chan = find_channel (fds[i].fd, 0); -          assert (chan); -          if ( nonblock ) -              fds[i].signaled = chan->readWouldBlock() ? 0 : 1; -          else -              fds[i].signaled = chan->waitForReadyRead( 1000 ) ? 1 : 0; -	  TRACE_ADD1 (dbg_help, "w0x%x ", fds[i].fd); -          if ( fds[i].signaled ) -              count++; -        } -      else if (fds[i].for_write) -        { -          const KDPipeIODevice * const chan = find_channel (fds[i].fd, 0); -          assert (chan); -          fds[i].signaled = nonblock ? ( chan->writeWouldBlock() ? 0 : 1 ) : 1; -          TRACE_ADD1 (dbg_help, "w0x%x ", fds[i].fd); -          if ( fds[i].signaled ) -              count++; -        } -    } -  TRACE_END (dbg_help, "]"); - -  return TRACE_SYSRES (count); -} - - -/* Look up the qiodevice for file descriptor FD.  */ -extern "C" -void * -gpgme_get_fdptr (int fd) -{ -  return find_channel (fd, 0); -} - - -/* Obsolete compatibility interface.  */ -extern "C" -void * -gpgme_get_giochannel (int fd) -{ -  return NULL; -} - - -int -_gpgme_io_dup (int fd) -{ -    assert( iodevice_table[fd] ); -    iodevice_table[fd]->ref(); -    return fd; -} - - -extern "C" -int -_gpgme_io_socket (int domain, int type, int proto) -{ -  errno = EIO; -  return -1; -} - - -extern "C" -int -_gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen) -{ -  errno = EIO; -  return -1; -} | 
