src/gui/embedded/qunixsocket.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qunixsocket_p.h"
       
    43 
       
    44 // #define QUNIXSOCKET_DEBUG 1
       
    45 
       
    46 #include <QtCore/qsocketnotifier.h>
       
    47 #include <QtCore/qqueue.h>
       
    48 #include <QtCore/qdatetime.h>
       
    49 #include "private/qcore_unix_p.h" // overrides QT_OPEN
       
    50 
       
    51 #ifdef QUNIXSOCKET_DEBUG
       
    52 #include <QtCore/qdebug.h>
       
    53 #endif
       
    54 
       
    55 extern "C" {
       
    56 #include <unistd.h>
       
    57 #include <string.h>
       
    58 #include <errno.h>
       
    59 #include <sys/socket.h>
       
    60 #include <sys/un.h>
       
    61 };
       
    62 
       
    63 #define UNIX_PATH_MAX 108 // From unix(7)
       
    64 
       
    65 #ifdef QT_LINUXBASE
       
    66 // LSB doesn't declare ucred
       
    67 struct ucred
       
    68 {
       
    69     pid_t pid;                    /* PID of sending process.  */
       
    70     uid_t uid;                    /* UID of sending process.  */
       
    71     gid_t gid;                    /* GID of sending process.  */
       
    72 };
       
    73 
       
    74 // LSB doesn't define the ones below
       
    75 #ifndef SO_PASSCRED
       
    76 #  define SO_PASSCRED   16
       
    77 #endif
       
    78 #ifndef SCM_CREDENTIALS
       
    79 #  define SCM_CREDENTIALS 0x02
       
    80 #endif
       
    81 #ifndef MSG_DONTWAIT
       
    82 #  define MSG_DONTWAIT 0x40
       
    83 #endif
       
    84 #ifndef MSG_NOSIGNAL
       
    85 #  define MSG_NOSIGNAL 0x4000
       
    86 #endif
       
    87 
       
    88 #endif // QT_LINUXBASE
       
    89 
       
    90 QT_BEGIN_NAMESPACE
       
    91 
       
    92 ///////////////////////////////////////////////////////////////////////////////
       
    93 // class QUnixSocketRights
       
    94 ///////////////////////////////////////////////////////////////////////////////
       
    95 /*!
       
    96   \class QUnixSocketRights
       
    97   \internal
       
    98 
       
    99   \brief The QUnixSocketRights class encapsulates QUnixSocket rights data.
       
   100   \omit
       
   101   \ingroup Platform::DeviceSpecific
       
   102   \ingroup Platform::OS
       
   103   \ingroup Platform::Communications
       
   104   \endomit
       
   105   \ingroup qws
       
   106 
       
   107   \l QUnixSocket allows you to transfer Unix file descriptors between processes.
       
   108   A file descriptor is referred to as "rights data" as it allows one process to
       
   109   transfer its right to access a resource to another.
       
   110 
       
   111   The Unix system verifies resource permissions only when the resource is first
       
   112   opened.  For example, consider a file on disk readable only by the user "qt".
       
   113   A process running as user "qt" will be able to open this file for reading.
       
   114   If, while the process was still reading from the file, the ownership was
       
   115   changed from user "qt" to user "root", the process would be allowed to
       
   116   continue reading from the file, even though attempting to reopen the file
       
   117   would be denied.  Permissions are associated with special descriptors called
       
   118   file descriptors which are returned to a process after it initially opens a
       
   119   resource.
       
   120 
       
   121   File descriptors can be duplicated within a process through the dup(2) system
       
   122   call.  File descriptors can be passed between processes using the
       
   123   \l QUnixSocket class in the same way.  Even though the receiving process never
       
   124   opened the resource directly, it has the same permissions to access it as the
       
   125   process that did.
       
   126 
       
   127   \sa QUnixSocket
       
   128  */
       
   129 struct QUnixSocketRightsPrivate : public QSharedData
       
   130 {
       
   131     virtual ~QUnixSocketRightsPrivate() {
       
   132 #ifdef QUNIXSOCKET_DEBUG
       
   133         int closerv =
       
   134 #endif
       
   135             QT_CLOSE(fd);
       
   136 #ifdef QUNIXSOCKET_DEBUG
       
   137         if(0 != closerv) {
       
   138             qDebug() << "QUnixSocketRightsPrivate: Unable to close managed"
       
   139                         " file descriptor (" << ::strerror(errno) << ')';
       
   140         }
       
   141 #endif
       
   142     }
       
   143 
       
   144     int fd;
       
   145 };
       
   146 
       
   147 /*!
       
   148   Create a new QUnixSocketRights instance containing the file descriptor \a fd.
       
   149   \a fd will be dup(2)'d internally, so the application is free to close \a fd
       
   150   following this call.
       
   151 
       
   152   If the dup(2) fails, or you pass an invalid \a fd, an
       
   153   \l {QUnixSocketRights::isValid()}{invalid } object will be
       
   154   constructed.
       
   155 
       
   156   QUnixSocketRights instances are immutable and the internal file descriptor
       
   157   will be shared between any copies made of this object.  The system will
       
   158   close(2) the file descriptor once it is no longer needed.
       
   159   */
       
   160 QUnixSocketRights::QUnixSocketRights(int fd)
       
   161 {
       
   162     d = new QUnixSocketRightsPrivate();
       
   163     if(-1 == fd) {
       
   164         d->fd = -1;
       
   165     } else {
       
   166         d->fd = qt_safe_dup(fd);
       
   167 #ifdef QUNIXSOCKET_DEBUG
       
   168         if(-1 == d->fd) {
       
   169             qDebug() << "QUnixSocketRights: Unable to duplicate fd "
       
   170                      << fd << " (" << ::strerror(errno) << ')';
       
   171         }
       
   172 #endif
       
   173     }
       
   174 }
       
   175 
       
   176 /*!
       
   177   \internal
       
   178 
       
   179   Construct a QUnixSocketRights instance on \a fd without dup(2)'ing the file
       
   180   descriptor.
       
   181   */
       
   182 QUnixSocketRights::QUnixSocketRights(int fd,int)
       
   183 {
       
   184     Q_ASSERT(-1 != fd);
       
   185     d = new QUnixSocketRightsPrivate();
       
   186     d->fd = fd;
       
   187 }
       
   188 
       
   189 /*!
       
   190   Destroys the QUnixSocketRights instance.
       
   191   */
       
   192 QUnixSocketRights::~QUnixSocketRights()
       
   193 {
       
   194 }
       
   195 
       
   196 /*!
       
   197   Create a copy of \a other.
       
   198   */
       
   199 QUnixSocketRights &
       
   200 QUnixSocketRights::operator=(const QUnixSocketRights & other)
       
   201 {
       
   202     d = other.d;
       
   203     return *this;
       
   204 }
       
   205 
       
   206 /*!
       
   207   Create a copy of \a other.
       
   208   */
       
   209 QUnixSocketRights::QUnixSocketRights(const QUnixSocketRights & other)
       
   210 : d(other.d)
       
   211 {
       
   212 }
       
   213 
       
   214 /*!
       
   215   Returns true if this QUnixSocketRights instance is managing a valid file
       
   216   descriptor.  This method is equivalent to (-1 != peekFd()).
       
   217 
       
   218   \sa QUnixSocketRights::peekFd()
       
   219   */
       
   220 bool QUnixSocketRights::isValid() const
       
   221 {
       
   222     return d->fd != -1;
       
   223 }
       
   224 
       
   225 /*!
       
   226   Return a duplicate of the file descriptor contained in this object.  If this
       
   227   is an \l {QUnixSocketRights::isValid()}{invalid } object, or the
       
   228   dup(2) call fails, an invalid file descriptor (-1) will be returned.
       
   229 
       
   230   \sa QUnixSocketRights::peekFd()
       
   231   */
       
   232 int QUnixSocketRights::dupFd() const
       
   233 {
       
   234     if(-1 == d->fd) return -1;
       
   235 
       
   236     int rv = qt_safe_dup(d->fd);
       
   237 
       
   238 #ifdef QUNIXSOCKET_DEBUG
       
   239     if(-1 == rv)
       
   240         qDebug() << "QUnixSocketRights: Unable to duplicate managed file "
       
   241                     "descriptor (" << ::strerror(errno) << ')';
       
   242 #endif
       
   243 
       
   244     return rv;
       
   245 }
       
   246 
       
   247 /*!
       
   248   Returns the file descriptor contained in this object.  If this
       
   249   is an \l {QUnixSocketRights::isValid()}{invalid } object an invalid
       
   250   file descriptor (-1) will be returned.
       
   251 
       
   252   The lifetime of this file descriptor is tied to the lifetime of the
       
   253   QUnixSocketRights instance.  The file descriptor returned by this method
       
   254   \e may be close(2)'d when the QUnixSocketRights instance is destroyed.  If
       
   255   you want to continue to use the file descriptor use
       
   256   \l QUnixSocketRights::dupFd() instead.
       
   257 
       
   258   \sa QUnixSocketRights::dupFd()
       
   259   */
       
   260 int QUnixSocketRights::peekFd() const
       
   261 {
       
   262     return d->fd;
       
   263 }
       
   264 
       
   265 ///////////////////////////////////////////////////////////////////////////////
       
   266 // class QUnixSocketMessage
       
   267 ///////////////////////////////////////////////////////////////////////////////
       
   268 struct QUnixSocketMessagePrivate : public QSharedData
       
   269 {
       
   270     QUnixSocketMessagePrivate()
       
   271     : state(Default), vec(0), iovecLen(0), dataSize(0) {}
       
   272     QUnixSocketMessagePrivate(const QByteArray & b)
       
   273     : bytes(b), state(Default), vec(0), iovecLen(0), dataSize(0) {}
       
   274     QUnixSocketMessagePrivate(const QByteArray & b,
       
   275                               const QList<QUnixSocketRights> & r)
       
   276     : bytes(b), rights(r), state(Default), vec(0), iovecLen(0), dataSize(0) {}
       
   277 
       
   278     int size() const { return vec ? dataSize : bytes.size(); }
       
   279     void removeBytes( unsigned int );
       
   280 
       
   281     QByteArray bytes;
       
   282     QList<QUnixSocketRights> rights;
       
   283 
       
   284     enum AncillaryDataState {
       
   285         Default = 0x00,
       
   286         Truncated = 0x01,
       
   287         Credential = 0x02
       
   288     };
       
   289     AncillaryDataState state;
       
   290 
       
   291     pid_t pid;
       
   292     gid_t gid;
       
   293     uid_t uid;
       
   294 
       
   295     ::iovec *vec;
       
   296     int iovecLen;  // number of vectors in array
       
   297     int dataSize;  // total size of vectors = payload
       
   298 };
       
   299 
       
   300 /*!
       
   301   \internal
       
   302   Remove \a bytesToDequeue bytes from the front of this message
       
   303 */
       
   304 void QUnixSocketMessagePrivate::removeBytes( unsigned int bytesToDequeue )
       
   305 {
       
   306     if ( vec )
       
   307     {
       
   308         ::iovec *vecPtr = vec;
       
   309         if ( bytesToDequeue > (unsigned int)dataSize ) bytesToDequeue = dataSize;
       
   310         while ( bytesToDequeue > 0 && iovecLen > 0 )
       
   311         {
       
   312             if ( vecPtr->iov_len > bytesToDequeue )
       
   313             {
       
   314                 // dequeue the bytes by taking them off the front of the
       
   315                 // current vector.  since we don't own the iovec, its okay
       
   316                 // to "leak" this away by pointing past it
       
   317                 char **base = reinterpret_cast<char**>(&(vecPtr->iov_base));
       
   318                 *base += bytesToDequeue;
       
   319                 vecPtr->iov_len -= bytesToDequeue;
       
   320                 bytesToDequeue = 0;
       
   321             }
       
   322             else
       
   323             {
       
   324                 // dequeue bytes by skipping a whole vector.  again, its ok
       
   325                 // to lose the pointers to this data
       
   326                 bytesToDequeue -= vecPtr->iov_len;
       
   327                 iovecLen--;
       
   328                 vecPtr++;
       
   329             }
       
   330         }
       
   331         dataSize -= bytesToDequeue;
       
   332         if ( iovecLen == 0 ) vec = 0;
       
   333     }
       
   334     else
       
   335     {
       
   336         bytes.remove(0, bytesToDequeue );
       
   337     }
       
   338 }
       
   339 
       
   340 
       
   341 /*!
       
   342   \class QUnixSocketMessage
       
   343   \internal
       
   344 
       
   345   \brief The QUnixSocketMessage class encapsulates a message sent or received
       
   346   through the QUnixSocket class.
       
   347   \omit
       
   348   \ingroup Platform::DeviceSpecific
       
   349   \ingroup Platform::OS
       
   350   \ingroup Platform::Communications
       
   351   \endomit
       
   352   \ingroup qws
       
   353 
       
   354   In addition to transmitting regular byte stream data, messages sent over Unix
       
   355   domain sockets may have special ancillary properties.  QUnixSocketMessage
       
   356   instances allow programmers to retrieve and control these properties.
       
   357 
       
   358   Every QUnixSocketMessage sent has an associated set of credentials.  A
       
   359   message's credentials consist of the process id, the user id and the group id
       
   360   of the sending process.  Normally these credentials are set automatically for
       
   361   you by the QUnixSocketMessage class and can be queried by the receiving
       
   362   process using the \l QUnixSocketMessage::processId(),
       
   363   \l QUnixSocketMessage::userId() and \l QUnixSocketMessage::groupId() methods
       
   364   respectively.
       
   365 
       
   366   Advanced applications may wish to change the credentials that their message
       
   367   is sent with, and may do so though the \l QUnixSocketMessage::setProcessId(),
       
   368   \l QUnixSocketMessage::setUserId() and \l QUnixSocketMessage::setGroupId()
       
   369   methods.  The validity of these credentials is verified by the system kernel.
       
   370   Only the root user can send messages with credentials that are not his own.
       
   371   Sending of the message will fail for any non-root user who attempts to
       
   372   fabricate credentials.  Note that this failure is enforced by the system
       
   373   kernel - receivers can trust the accuracy of credential data!
       
   374 
       
   375   Unix domain socket messages may also be used to transmit Unix file descriptors
       
   376   between processes.  In this context, file descriptors are known as rights data
       
   377   and are encapsulated by the \l QUnixSocketRights class.  Senders can set the
       
   378   file descriptors to transmit using the \l QUnixSocketMessage::setRights() and
       
   379   receivers can retrieve this data through a call to
       
   380   \l QUnixSocketMessage::rights().  \l QUnixSocket and \l QUnixSocketRights
       
   381   discuss the specific copy and ordering semantic associated with rights data.
       
   382 
       
   383   QUnixSocketMessage messages are sent by the \l QUnixSocket::write() method.
       
   384   Like any normal network message, attempting to transmit an empty
       
   385   QUnixSocketMessage will succeed, but result in a no-op.  Limitations in the
       
   386   Unix domain protocol semantic will cause a transmission of a
       
   387   QUnixSocketMessage with rights data, but no byte data portion, to fail.
       
   388 
       
   389   \sa QUnixSocket QUnixSocketRights
       
   390   */
       
   391 
       
   392 /*!
       
   393   Construct an empty QUnixSocketMessage.  This instance will have not data and
       
   394   no rights information.  The message's credentials will be set to the
       
   395   application's default credentials.
       
   396   */
       
   397 QUnixSocketMessage::QUnixSocketMessage()
       
   398 : d(new QUnixSocketMessagePrivate())
       
   399 {
       
   400 }
       
   401 
       
   402 /*!
       
   403   Construct a QUnixSocketMessage with an initial data payload of \a bytes.  The
       
   404   message's credentials will be set to the application's default credentials.
       
   405   */
       
   406 QUnixSocketMessage::QUnixSocketMessage(const QByteArray & bytes)
       
   407 : d(new QUnixSocketMessagePrivate(bytes))
       
   408 {
       
   409 }
       
   410 
       
   411 /*!
       
   412   Construct a QUnixSocketMessage with an initial data payload of \a bytes and
       
   413   an initial rights payload of \a rights.  The message's credentials will be set
       
   414   to the application's default credentials.
       
   415 
       
   416   A message with rights data but an empty data payload cannot be transmitted
       
   417   by the system.
       
   418   */
       
   419 QUnixSocketMessage::QUnixSocketMessage(const QByteArray & bytes,
       
   420                                        const QList<QUnixSocketRights> & rights)
       
   421 : d(new QUnixSocketMessagePrivate(bytes, rights))
       
   422 {
       
   423 }
       
   424 
       
   425 /*!
       
   426   Create a copy of \a other.
       
   427   */
       
   428 QUnixSocketMessage::QUnixSocketMessage(const QUnixSocketMessage & other)
       
   429 : d(other.d)
       
   430 {
       
   431 }
       
   432 
       
   433 /*!
       
   434   \fn  QUnixSocketMessage::QUnixSocketMessage(const iovec* data, int vecLen)
       
   435 
       
   436   Construct a QUnixSocketMessage with an initial data payload of \a
       
   437   data which points to an array of \a vecLen iovec structures.  The
       
   438   message's credentials will be set to the application's default
       
   439   credentials.
       
   440 
       
   441   This method can be used to avoid the overhead of copying buffers of data
       
   442   and will directly send the data pointed to by \a data on the socket.  It also
       
   443   avoids the syscall overhead of making a number of small socket write calls,
       
   444   if a number of data items can be delivered with one write.
       
   445 
       
   446   Caller must ensure the iovec * \a data remains valid until the message
       
   447   is flushed.  Caller retains ownership of the iovec structs.
       
   448   */
       
   449 QUnixSocketMessage::QUnixSocketMessage(const ::iovec* data, int vecLen )
       
   450 : d(new QUnixSocketMessagePrivate())
       
   451 {
       
   452     for ( int v = 0; v < vecLen; v++ )
       
   453         d->dataSize += data[v].iov_len;
       
   454     d->vec = const_cast<iovec*>(data);
       
   455     d->iovecLen = vecLen;
       
   456 }
       
   457 
       
   458 /*!
       
   459   Assign the contents of \a other to this object.
       
   460   */
       
   461 QUnixSocketMessage & QUnixSocketMessage::operator=(const QUnixSocketMessage & other)
       
   462 {
       
   463     d = other.d;
       
   464     return *this;
       
   465 }
       
   466 
       
   467 /*!
       
   468   Destroy this instance.
       
   469   */
       
   470 QUnixSocketMessage::~QUnixSocketMessage()
       
   471 {
       
   472 }
       
   473 
       
   474 /*!
       
   475   Set the data portion of the message to \a bytes.
       
   476 
       
   477   \sa QUnixSocketMessage::bytes()
       
   478   */
       
   479 void QUnixSocketMessage::setBytes(const QByteArray & bytes)
       
   480 {
       
   481     d.detach();
       
   482     d->bytes = bytes;
       
   483 }
       
   484 
       
   485 /*!
       
   486   Set the rights portion of the message to \a rights.
       
   487 
       
   488   A message with rights data but an empty byte data payload cannot be
       
   489   transmitted by the system.
       
   490 
       
   491   \sa QUnixSocketMessage::rights()
       
   492   */
       
   493 void QUnixSocketMessage::setRights(const QList<QUnixSocketRights> & rights)
       
   494 {
       
   495     d.detach();
       
   496     d->rights = rights;
       
   497 }
       
   498 
       
   499 /*!
       
   500   Return the rights portion of the message.
       
   501 
       
   502   \sa QUnixSocketMessage::setRights()
       
   503   */
       
   504 const QList<QUnixSocketRights> & QUnixSocketMessage::rights() const
       
   505 {
       
   506     return d->rights;
       
   507 }
       
   508 
       
   509 /*!
       
   510   Returns true if the rights portion of the message was truncated on reception
       
   511   due to insufficient buffer size.  The rights buffer size can be adjusted
       
   512   through calls to the \l QUnixSocket::setRightsBufferSize() method.
       
   513   \l QUnixSocket contains a discussion of the buffering and truncation
       
   514   characteristics of the Unix domain protocol.
       
   515 
       
   516   \sa QUnixSocket QUnixSocket::setRightsBufferSize()
       
   517   */
       
   518 bool QUnixSocketMessage::rightsWereTruncated() const
       
   519 {
       
   520     return d->state & QUnixSocketMessagePrivate::Truncated;
       
   521 }
       
   522 
       
   523 /*!
       
   524   Return the data portion of the message.
       
   525 
       
   526   \sa QUnixSocketMessage::setBytes()
       
   527   */
       
   528 const QByteArray & QUnixSocketMessage::bytes() const
       
   529 {
       
   530     return d->bytes;
       
   531 }
       
   532 
       
   533 /*!
       
   534   Returns the process id credential associated with this message.
       
   535 
       
   536   \sa QUnixSocketMessage::setProcessId()
       
   537   */
       
   538 pid_t QUnixSocketMessage::processId() const
       
   539 {
       
   540     if(QUnixSocketMessagePrivate::Credential & d->state)
       
   541         return d->pid;
       
   542     else
       
   543         return ::getpid();
       
   544 }
       
   545 
       
   546 /*!
       
   547   Returns the user id credential associated with this message.
       
   548 
       
   549   \sa QUnixSocketMessage::setUserId()
       
   550   */
       
   551 uid_t QUnixSocketMessage::userId() const
       
   552 {
       
   553     if(QUnixSocketMessagePrivate::Credential & d->state)
       
   554         return d->uid;
       
   555     else
       
   556         return ::geteuid();
       
   557 }
       
   558 
       
   559 /*!
       
   560   Returns the group id credential associated with this message.
       
   561 
       
   562   \sa QUnixSocketMessage::setGroupId()
       
   563   */
       
   564 gid_t QUnixSocketMessage::groupId() const
       
   565 {
       
   566     if(QUnixSocketMessagePrivate::Credential & d->state)
       
   567         return d->gid;
       
   568     else
       
   569         return ::getegid();
       
   570 }
       
   571 
       
   572 /*!
       
   573   Set the process id credential associated with this message to \a pid.  Unless
       
   574   you are the root user, setting a fraudulant credential will cause this message
       
   575   to fail.
       
   576 
       
   577   \sa QUnixSocketMessage::processId()
       
   578  */
       
   579 void QUnixSocketMessage::setProcessId(pid_t pid)
       
   580 {
       
   581     if(!(d->state & QUnixSocketMessagePrivate::Credential)) {
       
   582         d->state = (QUnixSocketMessagePrivate::AncillaryDataState)( d->state | QUnixSocketMessagePrivate::Credential );
       
   583         d->uid = ::geteuid();
       
   584         d->gid = ::getegid();
       
   585     }
       
   586     d->pid = pid;
       
   587 }
       
   588 
       
   589 /*!
       
   590   Set the user id credential associated with this message to \a uid.  Unless
       
   591   you are the root user, setting a fraudulant credential will cause this message
       
   592   to fail.
       
   593 
       
   594   \sa QUnixSocketMessage::userId()
       
   595  */
       
   596 void QUnixSocketMessage::setUserId(uid_t uid)
       
   597 {
       
   598     if(!(d->state & QUnixSocketMessagePrivate::Credential)) {
       
   599         d->state = (QUnixSocketMessagePrivate::AncillaryDataState)( d->state | QUnixSocketMessagePrivate::Credential );
       
   600         d->pid = ::getpid();
       
   601         d->gid = ::getegid();
       
   602     }
       
   603     d->uid = uid;
       
   604 }
       
   605 
       
   606 /*!
       
   607   Set the group id credential associated with this message to \a gid.  Unless
       
   608   you are the root user, setting a fraudulant credential will cause this message
       
   609   to fail.
       
   610 
       
   611   \sa QUnixSocketMessage::groupId()
       
   612  */
       
   613 void QUnixSocketMessage::setGroupId(gid_t gid)
       
   614 {
       
   615     if(!(d->state & QUnixSocketMessagePrivate::Credential)) {
       
   616         d->state = (QUnixSocketMessagePrivate::AncillaryDataState)( d->state | QUnixSocketMessagePrivate::Credential );
       
   617         d->pid = ::getpid();
       
   618         d->uid = ::geteuid();
       
   619     }
       
   620     d->gid = gid;
       
   621 }
       
   622 
       
   623 /*!
       
   624   Return true if this message is valid.  A message with rights data but an empty
       
   625   byte data payload cannot be transmitted by the system and is marked as
       
   626   invalid.
       
   627   */
       
   628 bool QUnixSocketMessage::isValid() const
       
   629 {
       
   630     return d->rights.isEmpty() || !d->bytes.isEmpty();
       
   631 }
       
   632 
       
   633 ///////////////////////////////////////////////////////////////////////////////
       
   634 // class QUnixSocket
       
   635 ///////////////////////////////////////////////////////////////////////////////
       
   636 #define QUNIXSOCKET_DEFAULT_READBUFFER 1024
       
   637 #define QUNIXSOCKET_DEFAULT_ANCILLARYBUFFER 0
       
   638 
       
   639 /*!
       
   640   \class QUnixSocket
       
   641   \internal
       
   642 
       
   643   \brief The QUnixSocket class provides a Unix domain socket.
       
   644 
       
   645   \omit
       
   646   \ingroup Platform::DeviceSpecific
       
   647   \ingroup Platform::OS
       
   648   \ingroup Platform::Communications
       
   649   \endomit
       
   650   \ingroup qws
       
   651 
       
   652   Unix domain sockets provide an efficient mechanism for communications between
       
   653   Unix processes on the same machine.  Unix domain sockets support a reliable,
       
   654   stream-oriented, connection-oriented transport protocol, much like TCP
       
   655   sockets.  Unlike IP based sockets, the connection endpoint of a Unix domain
       
   656   socket is a file on disk of type socket.
       
   657 
       
   658   In addition to transporting raw data bytes, Unix domain sockets are able to
       
   659   transmit special ancillary data.  The two types of ancillary data supported
       
   660   by the QUnixSocket class are:
       
   661 
       
   662   \list
       
   663   \o Credential Data - Allows a receiver
       
   664   to reliably identify the process sending each message.
       
   665   \o \l {QUnixSocketRights}{Rights Data } - Allows Unix file descriptors
       
   666   to be transmitted between processes.
       
   667   \endlist
       
   668 
       
   669   Because of the need to support ancillary data, QUnixSocket is not a QIODevice,
       
   670   like QTcpSocket and QUdpSocket.  Instead, QUnixSocket contains a number of
       
   671   read and write methods that clients must invoke directly.  Rather than
       
   672   returning raw data bytes, \l QUnixSocket::read() returns \l QUnixSocketMessage
       
   673   instances that encapsulate the message's byte data and any other ancillary
       
   674   data.
       
   675 
       
   676   Ancillary data is transmitted "out of band".  Every \l QUnixSocketMessage
       
   677   received will have credential data associated with it that the client can
       
   678   access through calls to \l QUnixSocketMessage::processId(),
       
   679   \l QUnixSocketMessage::groupId() and \l QUnixSocketMessage::userId().
       
   680   Likewise, message creators can set the credential data to send through calls
       
   681   to \l QUnixSocketMessage::setProcessId(), \l QUnixSocketMessage::setGroupId()
       
   682   and \l QUnixSocketMessage::setUserId() respectively.  The authenticity of the
       
   683   credential values is verified by the system kernel and cannot be fabricated
       
   684   by unprivileged processes.  Only processes running as the root user can
       
   685   specify credential data that does not match the sending process.
       
   686 
       
   687   Unix file descriptors, known as "rights data", transmitted between processes
       
   688   appear as though they had been dup(2)'d between the two.  As Unix
       
   689   domain sockets present a continuous stream of bytes to the receiver, the
       
   690   rights data - which is transmitted out of band - must be "slotted" in at some
       
   691   point.  The rights data is logically associated with the first byte - called
       
   692   the anchor byte - of the \l QUnixSocketMessage to which they are attached.
       
   693   Received rights data will be available from the
       
   694   \l QUnixSocketMessage::rights() method for the \l QUnixSocketMessage
       
   695   instance that contains the anchor byte.
       
   696 
       
   697   In addition to a \l QUnixSocket::write() that takes a \l QUnixSocketMessage
       
   698   instance - allowing a client to transmit both byte and rights data - a
       
   699   number of convenience overloads are provided for use when only transmitting
       
   700   simple byte data.  Unix requires that at least one byte of raw data be
       
   701   transmitted in order to send rights data.  A \l QUnixSocketMessage instance
       
   702   with rights data, but no byte data, cannot be transmitted.
       
   703 
       
   704   Unix sockets present a stream interface, such that, for example, a single
       
   705   six byte transmission might be received as two three byte messages.  Rights
       
   706   data, on the other hand, is conceptually transmitted as unfragmentable
       
   707   datagrams.  If the receiving buffer is not large enough to contain all the
       
   708   transmitted rights information, the data is truncated and irretreivably lost.
       
   709   Users should use the \l QUnixSocket::setRightsBufferSize() method to control
       
   710   the buffer size used for this data, and develop protocols that avoid the
       
   711   problem.  If the buffer size is too small and rights data is truncated,
       
   712   the \l QUnixSocketMessage::rightsWereTruncated() flag will be set.
       
   713 
       
   714   \sa QUnixSocketMessage QUnixSocketRights
       
   715 */
       
   716 
       
   717 /*!
       
   718   \enum QUnixSocket::SocketError
       
   719 
       
   720   The SocketError enumeration represents the various errors that can occur on
       
   721   a Unix domain socket.  The most recent error for the socket is available
       
   722   through the \l QUnixSocket::error() method.
       
   723 
       
   724   \value NoError No error has occurred.
       
   725   \value InvalidPath An invalid path endpoint was passed to
       
   726          \l QUnixSocket::connect().  As defined by unix(7), invalid paths
       
   727          include an empty path, or what more than 107 characters long.
       
   728   \value ResourceError An error acquiring or manipulating the system's socket
       
   729          resources occurred.  For example, if the process runs out of available
       
   730          socket descriptors, a ResourceError will occur.
       
   731   \value NonexistentPath The endpoing passed to \l QUnixSocket::connect() does
       
   732          not refer to a Unix domain socket entity on disk.
       
   733   \value ConnectionRefused The connection to the specified endpoint was refused.
       
   734          Generally this means that there is no server listening on that
       
   735          endpoint.
       
   736   \value UnknownError An unknown error has occurred.
       
   737   \value ReadFailure An error occurred while reading bytes from the connection.
       
   738   \value WriteFailure An error occurred while writing bytes into the connection.
       
   739   */
       
   740 
       
   741 /*!
       
   742   \enum QUnixSocket::SocketState
       
   743 
       
   744   The SocketState enumeration represents the connection state of a QUnixSocket
       
   745   instance.
       
   746 
       
   747   \value UnconnectedState The connection is not established.
       
   748   \value ConnectedState The connection is established.
       
   749   \value ClosingState The connection is being closed, following a call to
       
   750          \l QUnixSocket::close().  While closing, any pending data will be
       
   751          transmitted, but further writes by the application will be refused.
       
   752   */
       
   753 
       
   754 /*
       
   755   \fn QUnixSocket::bytesWritten(qint64 bytes)
       
   756 
       
   757   This signal is emitted every time a payload of data has been written to the
       
   758   connection.  The \a bytes argument is set to the number of bytes that were
       
   759   written in this payload.
       
   760 
       
   761   \sa QUnixSocket::readyRead()
       
   762 */
       
   763 
       
   764 /*
       
   765   \fn QUnixSocket::readyRead()
       
   766 
       
   767   This signal is emitted once every time new data is available for reading from
       
   768   the connection. It will only be emitted again once new data is available.
       
   769 
       
   770   \sa QUnixSocket::bytesWritten()
       
   771 */
       
   772 
       
   773 /*!
       
   774   \fn QUnixSocket::stateChanged(SocketState socketState)
       
   775 
       
   776   This signal is emitted each time the socket changes connection state.
       
   777   \a socketState will be set to the socket's new state.
       
   778 */
       
   779 
       
   780 class QUnixSocketPrivate : public QObject {
       
   781 Q_OBJECT
       
   782 public:
       
   783     QUnixSocketPrivate(QUnixSocket * _me)
       
   784     : me(_me), fd(-1), readNotifier(0), writeNotifier(0),
       
   785       state(QUnixSocket::UnconnectedState), error(QUnixSocket::NoError),
       
   786       writeQueueBytes(0), messageValid(false), dataBuffer(0),
       
   787       dataBufferLength(0), dataBufferCapacity(0), ancillaryBuffer(0),
       
   788       ancillaryBufferCount(0), closingTimer(0) {
       
   789           QObject::connect(this, SIGNAL(readyRead()), me, SIGNAL(readyRead()));
       
   790           QObject::connect(this, SIGNAL(bytesWritten(qint64)),
       
   791                            me, SIGNAL(bytesWritten(qint64)));
       
   792       }
       
   793     ~QUnixSocketPrivate()
       
   794     {
       
   795         if(dataBuffer)
       
   796             delete [] dataBuffer;
       
   797         if(ancillaryBuffer)
       
   798             delete [] ancillaryBuffer;
       
   799     }
       
   800 
       
   801     enum { CausedAbort = 0x70000000 };
       
   802 
       
   803     QUnixSocket * me;
       
   804 
       
   805     int fd;
       
   806 
       
   807     QSocketNotifier * readNotifier;
       
   808     QSocketNotifier * writeNotifier;
       
   809 
       
   810     QUnixSocket::SocketState state;
       
   811     QUnixSocket::SocketError error;
       
   812 
       
   813     QQueue<QUnixSocketMessage> writeQueue;
       
   814     unsigned int writeQueueBytes;
       
   815 
       
   816     bool messageValid;
       
   817     ::msghdr message;
       
   818     inline void flushAncillary()
       
   819     {
       
   820         if(!messageValid) return;
       
   821         ::cmsghdr * h = (::cmsghdr *)CMSG_FIRSTHDR(&(message));
       
   822         while(h) {
       
   823 
       
   824             if(SCM_RIGHTS == h->cmsg_type) {
       
   825                 int * fds = (int *)CMSG_DATA(h);
       
   826                 int numFds = (h->cmsg_len - CMSG_LEN(0)) / sizeof(int);
       
   827 
       
   828                 for(int ii = 0; ii < numFds; ++ii)
       
   829                     QT_CLOSE(fds[ii]);
       
   830             }
       
   831 
       
   832             h = (::cmsghdr *)CMSG_NXTHDR(&(message), h);
       
   833         }
       
   834 
       
   835         messageValid = false;
       
   836     }
       
   837 
       
   838 
       
   839     char * dataBuffer;
       
   840     unsigned int dataBufferLength;
       
   841     unsigned int dataBufferCapacity;
       
   842 
       
   843     char * ancillaryBuffer;
       
   844     inline unsigned int ancillaryBufferCapacity()
       
   845     {
       
   846         return CMSG_SPACE(sizeof(::ucred)) + CMSG_SPACE(sizeof(int) * ancillaryBufferCount);
       
   847     }
       
   848     unsigned int ancillaryBufferCount;
       
   849 
       
   850     QByteArray address;
       
   851 
       
   852     int closingTimer;
       
   853 
       
   854     virtual void timerEvent(QTimerEvent *)
       
   855     {
       
   856         me->abort();
       
   857         killTimer(closingTimer);
       
   858         closingTimer = 0;
       
   859     }
       
   860 signals:
       
   861     void readyRead();
       
   862     void bytesWritten(qint64);
       
   863 
       
   864 public slots:
       
   865     void readActivated();
       
   866     qint64 writeActivated();
       
   867 };
       
   868 
       
   869 /*!
       
   870   Construct a QUnixSocket instance, with \a parent.
       
   871 
       
   872   The read buffer is initially set to 1024 bytes, and the rights buffer to 0
       
   873   entries.
       
   874 
       
   875   \sa QUnixSocket::readBufferSize() QUnixSocket::rightsBufferSize()
       
   876   */
       
   877 QUnixSocket::QUnixSocket(QObject * parent)
       
   878 : QIODevice(parent), d(new QUnixSocketPrivate(this))
       
   879 {
       
   880     setOpenMode(QIODevice::NotOpen);
       
   881     setReadBufferSize(QUNIXSOCKET_DEFAULT_READBUFFER);
       
   882     setRightsBufferSize(QUNIXSOCKET_DEFAULT_ANCILLARYBUFFER);
       
   883 }
       
   884 
       
   885 /*!
       
   886   Construct a QUnixSocket instance, with \a parent.
       
   887 
       
   888   The read buffer is initially set to \a readBufferSize bytes, and the rights
       
   889   buffer to \a rightsBufferSize entries.
       
   890 
       
   891   \sa QUnixSocket::readBufferSize() QUnixSocket::rightsBufferSize()
       
   892   */
       
   893 QUnixSocket::QUnixSocket(qint64 readBufferSize, qint64 rightsBufferSize,
       
   894                          QObject * parent)
       
   895 : QIODevice(parent), d(new QUnixSocketPrivate(this))
       
   896 {
       
   897     Q_ASSERT(readBufferSize > 0 && rightsBufferSize >= 0);
       
   898 
       
   899     setOpenMode(QIODevice::NotOpen);
       
   900     setReadBufferSize(readBufferSize);
       
   901     setRightsBufferSize(rightsBufferSize);
       
   902 }
       
   903 
       
   904 /*!
       
   905   Destroys the QUnixSocket instance.  Any unsent data is discarded.
       
   906   */
       
   907 QUnixSocket::~QUnixSocket()
       
   908 {
       
   909     abort();
       
   910     delete d;
       
   911 }
       
   912 
       
   913 /*!
       
   914   Attempt to connect to \a path.
       
   915 
       
   916   This method is synchronous and will return true if the connection succeeds and
       
   917   false otherwise.  In the case of failure, \l QUnixSocket::error() will be set
       
   918   accordingly.
       
   919 
       
   920   Any existing connection will be aborted, and all pending data will be
       
   921   discarded.
       
   922 
       
   923   \sa QUnixSocket::close() QUnixSocket::abort() QUnixSocket::error()
       
   924   */
       
   925 bool QUnixSocket::connect(const QByteArray & path)
       
   926 {
       
   927     int _true;
       
   928     int crv;
       
   929 #ifdef QUNIXSOCKET_DEBUG
       
   930     qDebug() << "QUnixSocket: Connect requested to '"
       
   931              << path << '\'';
       
   932 #endif
       
   933 
       
   934     abort(); // Reset any existing connection
       
   935 
       
   936     if(UnconnectedState != d->state) // abort() caused a signal and someone messed
       
   937                                  // with us.  We'll assume they know what
       
   938                                  // they're doing and bail.  Alternative is to
       
   939                                  // have a special "Connecting" state
       
   940         return false;
       
   941 
       
   942 
       
   943     if(path.isEmpty() || path.size() > UNIX_PATH_MAX) {
       
   944         d->error = InvalidPath;
       
   945         return false;
       
   946     }
       
   947 
       
   948     // Create the socket
       
   949     d->fd = ::socket(PF_UNIX, SOCK_STREAM, 0);
       
   950     if(-1 == d->fd) {
       
   951 #ifdef QUNIXSOCKET_DEBUG
       
   952         qDebug() << "QUnixSocket: Unable to create socket ("
       
   953                  << strerror(errno) << ')';
       
   954 #endif
       
   955         d->error = ResourceError;
       
   956         goto connect_error;
       
   957     }
       
   958 
       
   959     // Set socket options
       
   960     _true = 1;
       
   961     crv = ::setsockopt(d->fd, SOL_SOCKET, SO_PASSCRED, (void *)&_true,
       
   962                        sizeof(int));
       
   963     if(-1 == crv) {
       
   964 #ifdef QUNIXSOCKET_DEBUG
       
   965         qDebug() << "QUnixSocket: Unable to configure socket ("
       
   966                  << ::strerror(errno) << ')';
       
   967 #endif
       
   968         d->error = ResourceError;
       
   969 
       
   970         goto connect_error;
       
   971     }
       
   972 
       
   973     // Construct our unix address
       
   974     struct ::sockaddr_un addr;
       
   975     addr.sun_family = AF_UNIX;
       
   976     ::memcpy(addr.sun_path, path.data(), path.size());
       
   977     if(path.size() < UNIX_PATH_MAX)
       
   978         addr.sun_path[path.size()] = '\0';
       
   979 
       
   980     // Attempt the connect
       
   981     crv = ::connect(d->fd, (sockaddr *)&addr, sizeof(sockaddr_un));
       
   982     if(-1 == crv) {
       
   983 #ifdef QUNIXSOCKET_DEBUG
       
   984         qDebug() << "QUnixSocket: Unable to connect ("
       
   985                  << ::strerror(errno) << ')';
       
   986 #endif
       
   987         if(ECONNREFUSED == errno)
       
   988             d->error = ConnectionRefused;
       
   989         else if(ENOENT == errno)
       
   990             d->error = NonexistentPath;
       
   991         else
       
   992             d->error = UnknownError;
       
   993 
       
   994         goto connect_error;
       
   995     }
       
   996 
       
   997     // We're connected!
       
   998     d->address = path;
       
   999     d->state = ConnectedState;
       
  1000     d->readNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, d);
       
  1001     d->writeNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Write, d);
       
  1002     QObject::connect(d->readNotifier, SIGNAL(activated(int)),
       
  1003                      d, SLOT(readActivated()));
       
  1004     QObject::connect(d->writeNotifier, SIGNAL(activated(int)),
       
  1005                      d, SLOT(writeActivated()));
       
  1006     d->readNotifier->setEnabled(true);
       
  1007     d->writeNotifier->setEnabled(false);
       
  1008     setOpenMode(QIODevice::ReadWrite);
       
  1009     emit stateChanged(ConnectedState);
       
  1010 
       
  1011 #ifdef QUNIXSOCKET_DEBUG
       
  1012     qDebug() << "QUnixSocket: Connected to " << path;
       
  1013 #endif
       
  1014     return true;
       
  1015 
       
  1016 connect_error: // Cleanup failed connection
       
  1017     if(-1 != d->fd) {
       
  1018 #ifdef QUNIXSOCKET_DEBUG
       
  1019         int closerv =
       
  1020 #endif
       
  1021             QT_CLOSE(d->fd);
       
  1022 #ifdef QUNIXSOCKET_DEBUG
       
  1023         if(0 != closerv) {
       
  1024             qDebug() << "QUnixSocket: Unable to close file descriptor after "
       
  1025                         "failed connect (" << ::strerror(errno) << ')';
       
  1026         }
       
  1027 #endif
       
  1028     }
       
  1029     d->fd = -1;
       
  1030     return false;
       
  1031 }
       
  1032 
       
  1033 /*!
       
  1034   Sets the socket descriptor to use to \a socketDescriptor, bypassing
       
  1035   QUnixSocket's connection infrastructure, and return true on success and false
       
  1036   on failure.  \a socketDescriptor must be in the connected state, and must be
       
  1037   a Unix domain socket descriptor.  Following a successful call to this method,
       
  1038   the QUnixSocket instance will be in the Connected state and will have assumed
       
  1039   ownership of \a socketDescriptor.
       
  1040 
       
  1041   Any existing connection will be aborted, and all pending data will be
       
  1042   discarded.
       
  1043 
       
  1044   \sa QUnixSocket::connect()
       
  1045 */
       
  1046 bool QUnixSocket::setSocketDescriptor(int socketDescriptor)
       
  1047 {
       
  1048     abort();
       
  1049 
       
  1050     if(UnconnectedState != state()) // See QUnixSocket::connect()
       
  1051         return false;
       
  1052 
       
  1053     // Attempt to set the socket options
       
  1054     if(-1 == socketDescriptor) {
       
  1055 #ifdef QUNIXSOCKET_DEBUG
       
  1056         qDebug() << "QUnixSocket: User provided socket is invalid";
       
  1057 #endif
       
  1058         d->error = ResourceError;
       
  1059         return false;
       
  1060     }
       
  1061 
       
  1062     // Set socket options
       
  1063     int _true = 1;
       
  1064     int crv = ::setsockopt(socketDescriptor, SOL_SOCKET,
       
  1065                            SO_PASSCRED, (void *)&_true, sizeof(int));
       
  1066     if(-1 == crv) {
       
  1067 #ifdef QUNIXSOCKET_DEBUG
       
  1068         qDebug() << "QUnixSocket: Unable to configure client provided socket ("
       
  1069                  << ::strerror(errno) << ')';
       
  1070 #endif
       
  1071         d->error = ResourceError;
       
  1072 
       
  1073         return false;
       
  1074     }
       
  1075 
       
  1076     d->fd = socketDescriptor;
       
  1077     d->state = ConnectedState;
       
  1078     d->address = QByteArray();
       
  1079     setOpenMode(QIODevice::ReadWrite);
       
  1080     d->readNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, d);
       
  1081     d->writeNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Write, d);
       
  1082     QObject::connect(d->readNotifier, SIGNAL(activated(int)),
       
  1083                      d, SLOT(readActivated()));
       
  1084     QObject::connect(d->writeNotifier, SIGNAL(activated(int)),
       
  1085                      d, SLOT(writeActivated()));
       
  1086     d->readNotifier->setEnabled(true);
       
  1087     d->writeNotifier->setEnabled(false);
       
  1088     emit stateChanged(d->state);
       
  1089 
       
  1090     return true;
       
  1091 }
       
  1092 
       
  1093 /*!
       
  1094   Returns the socket descriptor currently in use.  This method will return -1
       
  1095   if the QUnixSocket instance is in the UnconnectedState \l {QUnixSocket::state()}{state. }
       
  1096 
       
  1097   \sa QUnixSocket::setSocketDescriptor()
       
  1098   */
       
  1099 int QUnixSocket::socketDescriptor() const
       
  1100 {
       
  1101     return d->fd;
       
  1102 }
       
  1103 
       
  1104 /*!
       
  1105   Abort the connection.  This will immediately disconnect (if connected) and
       
  1106   discard any pending data.  Following a call to QUnixSocket::abort() the
       
  1107   object will always be in the disconnected \link QUnixSocket::state() state.
       
  1108   \endlink
       
  1109 
       
  1110   \sa QUnixSocket::close()
       
  1111 */
       
  1112 void QUnixSocket::abort()
       
  1113 {
       
  1114     setOpenMode(QIODevice::NotOpen);
       
  1115 
       
  1116     // We want to be able to use QUnixSocket::abort() to cleanup our state but
       
  1117     // also preserve the error message that caused the abort.  It is not
       
  1118     // possible to reorder code to do this:
       
  1119     //        abort();
       
  1120     //        d->error = SomeError
       
  1121     // as QUnixSocket::abort() might emit a signal and we need the error to be
       
  1122     // set within that signal.  So, if we want an error message to be preserved
       
  1123     // across a *single* call to abort(), we set the
       
  1124     // QUnixSocketPrivate::CausedAbort flag in the error.
       
  1125     if(d->error & QUnixSocketPrivate::CausedAbort)
       
  1126         d->error = (QUnixSocket::SocketError)(d->error &
       
  1127                                               ~QUnixSocketPrivate::CausedAbort);
       
  1128     else
       
  1129         d->error = NoError;
       
  1130 
       
  1131     if( UnconnectedState == d->state) return;
       
  1132 
       
  1133 #ifdef QUNIXSOCKET_DEBUG
       
  1134     int closerv =
       
  1135 #endif
       
  1136         ::close(d->fd);
       
  1137 #ifdef QUNIXSOCKET_DEBUG
       
  1138     if(0 != closerv) {
       
  1139         qDebug() << "QUnixSocket: Unable to close socket during abort ("
       
  1140                  << strerror(errno) << ')';
       
  1141     }
       
  1142 #endif
       
  1143 
       
  1144     // Reset variables
       
  1145     d->fd = -1;
       
  1146     d->state = UnconnectedState;
       
  1147     d->dataBufferLength = 0;
       
  1148     d->flushAncillary();
       
  1149     d->address = QByteArray();
       
  1150     if(d->readNotifier) {
       
  1151         d->readNotifier->setEnabled(false);
       
  1152         d->readNotifier->deleteLater();
       
  1153     }
       
  1154     if(d->writeNotifier) {
       
  1155         d->writeNotifier->setEnabled(false);
       
  1156         d->writeNotifier->deleteLater();
       
  1157     }
       
  1158     d->readNotifier = 0;
       
  1159     d->writeNotifier = 0;
       
  1160     d->writeQueue.clear();
       
  1161     d->writeQueueBytes = 0;
       
  1162     if(d->closingTimer) {
       
  1163         d->killTimer(d->closingTimer);
       
  1164     }
       
  1165     d->closingTimer = 0;
       
  1166     emit stateChanged(d->state);
       
  1167 }
       
  1168 
       
  1169 /*!
       
  1170   Close the connection.  The instance will enter the Closing
       
  1171   \l {QUnixSocket::state()}{state } until all pending data has been
       
  1172   transmitted, at which point it will enter the Unconnected state.
       
  1173 
       
  1174   Even if there is no pending data for transmission, the object will never
       
  1175   jump directly to Disconnect without first passing through the
       
  1176   Closing state.
       
  1177 
       
  1178   \sa QUnixSocket::abort()
       
  1179   */
       
  1180 void QUnixSocket::close()
       
  1181 {
       
  1182     if(ConnectedState != state()) return;
       
  1183 
       
  1184     d->state = ClosingState;
       
  1185     if(d->writeQueue.isEmpty()) {
       
  1186         d->closingTimer = d->startTimer(0); // Start a timer to "fake"
       
  1187                                             // completing writes
       
  1188     }
       
  1189     emit stateChanged(d->state);
       
  1190 }
       
  1191 
       
  1192 /*!
       
  1193     This function writes as much as possible from the internal write buffer to
       
  1194     the underlying socket, without blocking. If any data was written, this
       
  1195     function returns true; otherwise false is returned.
       
  1196 */
       
  1197 // Note! docs partially copied from QAbstractSocket::flush()
       
  1198 bool QUnixSocket::flush()
       
  1199 {
       
  1200     // This needs to have the same semantics as QAbstractSocket, if it is to
       
  1201     // be used interchangeably with that class.
       
  1202     if (d->writeQueue.isEmpty())
       
  1203         return false;
       
  1204 
       
  1205     d->writeActivated();
       
  1206     return true;
       
  1207 }
       
  1208 
       
  1209 /*!
       
  1210   Returns the last error to have occurred on this object.  This method is not
       
  1211   destructive, so multiple calls to QUnixSocket::error() will return the same
       
  1212   value.  The error is only reset by a call to \l QUnixSocket::connect() or
       
  1213   \l QUnixSocket::abort()
       
  1214   */
       
  1215 QUnixSocket::SocketError QUnixSocket::error() const
       
  1216 {
       
  1217     return (QUnixSocket::SocketError)
       
  1218         (d->error & ~QUnixSocketPrivate::CausedAbort);
       
  1219 }
       
  1220 
       
  1221 /*!
       
  1222   Returns the connection state of this instance.
       
  1223   */
       
  1224 QUnixSocket::SocketState QUnixSocket::state() const
       
  1225 {
       
  1226     return d->state;
       
  1227 }
       
  1228 
       
  1229 /*!
       
  1230   Returns the Unix path address passed to \l QUnixSocket::connect().  This
       
  1231   method will return an empty path if the object is in the Unconnected
       
  1232   \l {QUnixSocket::state()}{state } or was connected through a call
       
  1233   to \l QUnixSocket::setSocketDescriptor()
       
  1234 
       
  1235   \sa QUnixSocket::connect() QUnixSocket::setSocketDescriptor()
       
  1236   */
       
  1237 QByteArray QUnixSocket::address() const
       
  1238 {
       
  1239     return d->address;
       
  1240 }
       
  1241 
       
  1242 /*!
       
  1243   Returns the number of bytes available for immediate retrieval through a call
       
  1244   to \l QUnixSocket::read().
       
  1245   */
       
  1246 qint64 QUnixSocket::bytesAvailable() const
       
  1247 {
       
  1248     return QIODevice::bytesAvailable() + d->dataBufferLength;
       
  1249 }
       
  1250 
       
  1251 /*!
       
  1252   Returns the number of enqueued bytes still to be written to the socket.
       
  1253   */
       
  1254 qint64 QUnixSocket::bytesToWrite() const
       
  1255 {
       
  1256     return d->writeQueueBytes;
       
  1257 }
       
  1258 
       
  1259 /*!
       
  1260   Returns the size of the read buffer in bytes.  The read buffer size
       
  1261   determines the amount of byte data that can be read from the socket in one go.
       
  1262   The read buffer size caps the maximum value that can be returned by
       
  1263   \l QUnixSocket::bytesAvailable() and will always be greater than zero.  By
       
  1264   default, the read buffer size is 1024 bytes.
       
  1265 
       
  1266   The size of the read buffer is independent of the rights buffer, which can be
       
  1267   queried by \l QUnixSocket::rightsBufferSize().
       
  1268 
       
  1269   \sa QUnixSocket::setReadBufferSize()
       
  1270   */
       
  1271 qint64 QUnixSocket::readBufferSize() const
       
  1272 {
       
  1273     return d->dataBufferCapacity;
       
  1274 }
       
  1275 
       
  1276 /*!
       
  1277   Sets the \a size of the socket's read buffer in bytes.
       
  1278 
       
  1279   The size of the read buffer is independent of the rights buffer, which can be
       
  1280   set by \l QUnixSocket::setRightsBufferSize().
       
  1281 
       
  1282   Attempting to reduce the buffer size while bytes are available for reading
       
  1283   (ie. while the buffer is in use) will fail.
       
  1284 
       
  1285   \sa QUnixSocket::readBufferSize()
       
  1286   */
       
  1287 void QUnixSocket::setReadBufferSize(qint64 size)
       
  1288 {
       
  1289     Q_ASSERT(size > 0);
       
  1290     if(size == d->dataBufferCapacity || d->dataBufferLength) return;
       
  1291     if(d->dataBuffer) delete [] d->dataBuffer;
       
  1292     d->dataBuffer = new char[size];
       
  1293     d->dataBufferCapacity = size;
       
  1294 }
       
  1295 
       
  1296 /*!
       
  1297   Returns the size of the rights buffer in rights entries.  The rights buffer
       
  1298   size determines the number of rights transferences that can be received in
       
  1299   any message.  Unlike byte stream data which can be fragmented into many
       
  1300   smaller messages if the \link QUnixSocket::readBufferSize() read buffer
       
  1301   \endlink is not large enough to contain all the available data, rights data
       
  1302   is transmitted as unfragmentable datagrams.  If the rights buffer is not
       
  1303   large enough to contain this unfragmentable datagram, the datagram will be
       
  1304   truncated and rights data irretrievably lost.  If truncation occurs, the
       
  1305   \l QUnixSocketMessage::rightsWereTruncated() flag will be set.  By default
       
  1306   the rights buffer size is 0 entries - rights data cannot be received.
       
  1307 
       
  1308   The size of the rights buffer is independent of the read buffer, which can be
       
  1309   queried by \l QUnixSocket::readBufferSize().
       
  1310 
       
  1311   \sa QUnixSocket::setRightsBufferSize()
       
  1312   */
       
  1313 qint64 QUnixSocket::rightsBufferSize() const
       
  1314 {
       
  1315     return d->ancillaryBufferCount;
       
  1316 }
       
  1317 
       
  1318 /*!
       
  1319   Sets the \a size of the socket's rights buffer in rights entries.
       
  1320 
       
  1321   The size of the rights buffer is independent of the read buffer, which can be
       
  1322   set by \l QUnixSocket::setReadBufferSize().
       
  1323 
       
  1324   Attempting to reduce the buffer size while bytes are available for reading
       
  1325   (ie. while the buffer is in use) will fail.
       
  1326 
       
  1327   \sa QUnixSocket::rightsBufferSize()
       
  1328   */
       
  1329 void QUnixSocket::setRightsBufferSize(qint64 size)
       
  1330 {
       
  1331     Q_ASSERT(size >= 0);
       
  1332 
       
  1333     if((size == d->ancillaryBufferCount || d->dataBufferLength) &&
       
  1334             d->ancillaryBuffer)
       
  1335         return;
       
  1336 
       
  1337     qint64 byteSize = CMSG_SPACE(sizeof(::ucred)) +
       
  1338                       CMSG_SPACE(size * sizeof(int));
       
  1339 
       
  1340     if(d->ancillaryBuffer) delete [] d->ancillaryBuffer;
       
  1341     d->ancillaryBuffer = new char[byteSize];
       
  1342     d->ancillaryBufferCount = size;
       
  1343 }
       
  1344 
       
  1345 /*!
       
  1346   \overload
       
  1347 
       
  1348   Writes \a socketdata to the socket.  In addition to failing if the socket
       
  1349   is not in the Connected state, writing will fail if \a socketdata is
       
  1350   \l {QUnixSocketMessage::isValid()}{invalid. }
       
  1351 
       
  1352   Writes through the QUnixSocket class are asynchronous.  Rather than being
       
  1353   written immediately, data is enqueued and written once the application
       
  1354   reenters the Qt event loop and the socket becomes available for writing.
       
  1355   Thus, this method will only fail if the socket is not in the Connected state
       
  1356   - it is illegal to attempt a write on a Unconnected or Closing socket.
       
  1357 
       
  1358   Applications can monitor the progress of data writes through the
       
  1359   \l QUnixSocket::bytesWritten() signal and \l QUnixSocket::bytesToWrite()
       
  1360   method.
       
  1361 
       
  1362   \sa QUnixSocketMessage
       
  1363   */
       
  1364 qint64 QUnixSocket::write(const QUnixSocketMessage & socketdata)
       
  1365 {
       
  1366     if(ConnectedState != state() || !socketdata.isValid()) return -1;
       
  1367     if(socketdata.d->size() == 0) return 0;
       
  1368 
       
  1369     d->writeQueue.enqueue(socketdata);
       
  1370     d->writeQueueBytes += socketdata.d->size();
       
  1371     d->writeNotifier->setEnabled(true);
       
  1372 
       
  1373     return socketdata.d->size();
       
  1374 }
       
  1375 
       
  1376 /*!
       
  1377   Return the next available message, or an empty message if none is available.
       
  1378 
       
  1379   To avoid retrieving empty messages, applications should connect to the
       
  1380   \l QUnixSocket::readyRead() signal to be notified when new messages are
       
  1381   available or periodically poll the \l QUnixSocket::bytesAvailable() method.
       
  1382 
       
  1383   \sa QUnixSocket::readyRead() QUnixSocket::bytesAvailable()
       
  1384   */
       
  1385 QUnixSocketMessage QUnixSocket::read()
       
  1386 {
       
  1387     QUnixSocketMessage data;
       
  1388     if(!d->dataBufferLength)
       
  1389         return data;
       
  1390 
       
  1391     data.d->state = QUnixSocketMessagePrivate::Credential;
       
  1392 
       
  1393     // Bytes are easy
       
  1394     data.setBytes(QByteArray(d->dataBuffer, d->dataBufferLength));
       
  1395 
       
  1396     // Extract ancillary data
       
  1397     QList<QUnixSocketRights> a;
       
  1398 
       
  1399     ::cmsghdr * h = (::cmsghdr *)CMSG_FIRSTHDR(&(d->message));
       
  1400     while(h) {
       
  1401 
       
  1402         if(SCM_CREDENTIALS == h->cmsg_type) {
       
  1403             ::ucred * cred = (::ucred *)CMSG_DATA(h);
       
  1404 #ifdef QUNIXSOCKET_DEBUG
       
  1405             qDebug( "Credentials recd: pid %lu - gid %lu - uid %lu",
       
  1406                     cred->pid, cred->gid, cred->uid );
       
  1407 #endif
       
  1408             data.d->pid = cred->pid;
       
  1409             data.d->gid = cred->gid;
       
  1410             data.d->uid = cred->uid;
       
  1411 
       
  1412         } else if(SCM_RIGHTS == h->cmsg_type) {
       
  1413 
       
  1414             int * fds = (int *)CMSG_DATA(h);
       
  1415             int numFds = (h->cmsg_len - CMSG_LEN(0)) / sizeof(int);
       
  1416 
       
  1417             for(int ii = 0; ii < numFds; ++ii) {
       
  1418                 QUnixSocketRights qusr(fds[ii], 0);
       
  1419                 a.append(qusr);
       
  1420             }
       
  1421 
       
  1422         } else {
       
  1423 
       
  1424 #ifdef QUNIXSOCKET_DEBUG
       
  1425             qFatal("QUnixSocket: Unknown ancillary data type (%d) received.",
       
  1426                    h->cmsg_type);
       
  1427 #endif
       
  1428 
       
  1429         }
       
  1430 
       
  1431         h = (::cmsghdr *)CMSG_NXTHDR(&(d->message), h);
       
  1432     }
       
  1433 
       
  1434     if(d->message.msg_flags & MSG_CTRUNC) {
       
  1435         data.d->state = (QUnixSocketMessagePrivate::AncillaryDataState)(QUnixSocketMessagePrivate::Truncated |
       
  1436                                QUnixSocketMessagePrivate::Credential );
       
  1437     }
       
  1438 
       
  1439     if(!a.isEmpty())
       
  1440         data.d->rights = a;
       
  1441 
       
  1442     d->dataBufferLength = 0;
       
  1443     d->messageValid = false;
       
  1444     d->readNotifier->setEnabled(true);
       
  1445 
       
  1446     return data;
       
  1447 }
       
  1448 
       
  1449 /*! \internal */
       
  1450 bool QUnixSocket::isSequential() const
       
  1451 {
       
  1452     return true;
       
  1453 }
       
  1454 
       
  1455 /*! \internal */
       
  1456 bool QUnixSocket::waitForReadyRead(int msecs)
       
  1457 {
       
  1458     if(UnconnectedState == d->state)
       
  1459         return false;
       
  1460 
       
  1461     if(d->messageValid) {
       
  1462         return true;
       
  1463     }
       
  1464 
       
  1465     Q_ASSERT(-1 != d->fd);
       
  1466 
       
  1467     int     timeout = msecs;
       
  1468     struct  timeval tv;
       
  1469     struct  timeval *ptrTv = 0;
       
  1470     QTime   stopWatch;
       
  1471 
       
  1472     stopWatch.start();
       
  1473 
       
  1474     do
       
  1475     {
       
  1476         fd_set readset;
       
  1477 
       
  1478         FD_ZERO(&readset);
       
  1479         FD_SET(d->fd, &readset);
       
  1480 
       
  1481         if(-1 != msecs) {
       
  1482             tv.tv_sec = timeout / 1000;
       
  1483             tv.tv_usec = (timeout % 1000) * 1000;
       
  1484             ptrTv = &tv;
       
  1485         }
       
  1486 
       
  1487         int rv = ::select(d->fd + 1, &readset, 0, 0, ptrTv);
       
  1488         switch(rv) {
       
  1489             case 0:
       
  1490                 // timeout
       
  1491                 return false;
       
  1492             case 1:
       
  1493                 // ok
       
  1494                 d->readActivated();
       
  1495                 return true;
       
  1496             default:
       
  1497                 if (errno != EINTR)
       
  1498                     abort();    // error
       
  1499                 break;
       
  1500         }
       
  1501 
       
  1502         timeout = msecs - stopWatch.elapsed();
       
  1503     }
       
  1504     while (timeout > 0);
       
  1505 
       
  1506     return false;
       
  1507 }
       
  1508 
       
  1509 bool QUnixSocket::waitForBytesWritten(int msecs)
       
  1510 {
       
  1511     if(UnconnectedState == d->state)
       
  1512         return false;
       
  1513 
       
  1514     Q_ASSERT(-1 != d->fd);
       
  1515 
       
  1516     if ( d->writeQueue.isEmpty() )
       
  1517         return true;
       
  1518 
       
  1519     QTime stopWatch;
       
  1520     stopWatch.start();
       
  1521 
       
  1522     while ( true )
       
  1523     {
       
  1524         fd_set fdwrite;
       
  1525         FD_ZERO(&fdwrite);
       
  1526         FD_SET(d->fd, &fdwrite);
       
  1527         int timeout = msecs < 0 ? 0 : msecs - stopWatch.elapsed();
       
  1528         struct timeval tv;
       
  1529         struct timeval *ptrTv = 0;
       
  1530         if ( -1 != msecs )
       
  1531         {
       
  1532             tv.tv_sec = timeout / 1000;
       
  1533             tv.tv_usec = (timeout % 1000) * 1000;
       
  1534             ptrTv = &tv;
       
  1535         }
       
  1536 
       
  1537         int rv = ::select(d->fd + 1, 0, &fdwrite, 0, ptrTv);
       
  1538         switch ( rv )
       
  1539         {
       
  1540             case 0:
       
  1541                 // timeout
       
  1542                 return false;
       
  1543             case 1:
       
  1544             {
       
  1545                 // ok to write
       
  1546                 qint64 bytesWritten = d->writeActivated();
       
  1547                 if (bytesWritten == 0) {
       
  1548                     // We need to retry
       
  1549                     int delay = 1;
       
  1550                     do {
       
  1551                         if (-1 != msecs) {
       
  1552                             timeout = msecs - stopWatch.elapsed();
       
  1553                             if (timeout <= 0) {
       
  1554                                 // We have exceeded our allotted time
       
  1555                                 return false;
       
  1556                             } else {
       
  1557                                 if (delay > timeout)
       
  1558                                     delay = timeout;
       
  1559                             }
       
  1560                         }
       
  1561 
       
  1562                         // Pause before we make another attempt to send
       
  1563                         ::usleep(delay * 1000);
       
  1564                         if (delay < 1024)
       
  1565                             delay *= 2;
       
  1566 
       
  1567                         bytesWritten = d->writeActivated();
       
  1568                     } while (bytesWritten == 0);
       
  1569                 }
       
  1570                 return (bytesWritten != -1);
       
  1571             }
       
  1572             default:
       
  1573                 // error - or an uncaught signal!!!!!!!!!
       
  1574                 if ( rv == EINTR )
       
  1575                     continue;
       
  1576                 abort();
       
  1577                 return false;
       
  1578         }
       
  1579     }
       
  1580     return false; // fix warnings
       
  1581 }
       
  1582 
       
  1583 /*! \internal */
       
  1584 bool QUnixSocket::canReadLine() const
       
  1585 {
       
  1586     for(unsigned int ii = 0; ii < d->dataBufferLength; ++ii)
       
  1587         if(d->dataBuffer[ii] == '\n') return true;
       
  1588     return false;
       
  1589 }
       
  1590 
       
  1591 /*! \internal */
       
  1592 qint64 QUnixSocket::readData(char * data, qint64 maxSize)
       
  1593 {
       
  1594     Q_ASSERT(data);
       
  1595     if(0 >= maxSize) return 0;
       
  1596     if(!d->dataBufferLength) return 0;
       
  1597 
       
  1598     // Read data
       
  1599     unsigned int size = d->dataBufferLength>maxSize?maxSize:d->dataBufferLength;
       
  1600     memcpy(data, d->dataBuffer, size);
       
  1601     if(size == d->dataBufferLength) {
       
  1602         d->dataBufferLength = 0;
       
  1603     } else {
       
  1604         memmove(d->dataBuffer, d->dataBuffer + size, d->dataBufferLength - size);
       
  1605         d->dataBufferLength -= size;
       
  1606     }
       
  1607 
       
  1608 
       
  1609     // Flush ancillary
       
  1610     d->flushAncillary();
       
  1611 
       
  1612     if(0 == d->dataBufferLength)
       
  1613         d->readNotifier->setEnabled(true);
       
  1614 
       
  1615     return size;
       
  1616 }
       
  1617 
       
  1618 /*! \internal */
       
  1619 qint64 QUnixSocket::writeData (const char * data, qint64 maxSize)
       
  1620 {
       
  1621     return write(QUnixSocketMessage(QByteArray(data, maxSize)));
       
  1622 }
       
  1623 
       
  1624 qint64 QUnixSocketPrivate::writeActivated()
       
  1625 {
       
  1626     writeNotifier->setEnabled(false);
       
  1627 
       
  1628     QUnixSocketMessage & m = writeQueue.head();
       
  1629     const QList<QUnixSocketRights> & a = m.rights();
       
  1630 
       
  1631     //
       
  1632     // Construct the message
       
  1633     //
       
  1634     ::iovec vec;
       
  1635     if ( !m.d->vec ) // message does not already have an iovec
       
  1636     {
       
  1637         vec.iov_base = (void *)m.bytes().constData();
       
  1638         vec.iov_len = m.bytes().size();
       
  1639     }
       
  1640 
       
  1641     // Allocate the control buffer
       
  1642     ::msghdr sendmessage;
       
  1643     ::bzero(&sendmessage, sizeof(::msghdr));
       
  1644     if ( m.d->vec )
       
  1645     {
       
  1646         sendmessage.msg_iov = m.d->vec;
       
  1647         sendmessage.msg_iovlen = m.d->iovecLen;
       
  1648     }
       
  1649     else
       
  1650     {
       
  1651         sendmessage.msg_iov = &vec;
       
  1652         sendmessage.msg_iovlen = 1;
       
  1653     }
       
  1654     unsigned int required = CMSG_SPACE(sizeof(::ucred)) +
       
  1655                             a.size() * CMSG_SPACE(sizeof(int));
       
  1656     sendmessage.msg_control = new char[required];
       
  1657     ::bzero(sendmessage.msg_control, required);
       
  1658     sendmessage.msg_controllen = required;
       
  1659 
       
  1660     // Create ancillary buffer
       
  1661     ::cmsghdr * h = CMSG_FIRSTHDR(&sendmessage);
       
  1662 
       
  1663     if(m.d->state & QUnixSocketMessagePrivate::Credential) {
       
  1664         h->cmsg_len = CMSG_LEN(sizeof(::ucred));
       
  1665         h->cmsg_level = SOL_SOCKET;
       
  1666         h->cmsg_type = SCM_CREDENTIALS;
       
  1667         ((::ucred *)CMSG_DATA(h))->pid = m.d->pid;
       
  1668         ((::ucred *)CMSG_DATA(h))->gid = m.d->gid;
       
  1669         ((::ucred *)CMSG_DATA(h))->uid = m.d->uid;
       
  1670         h = CMSG_NXTHDR(&sendmessage, h);
       
  1671     } else {
       
  1672         sendmessage.msg_controllen -= CMSG_SPACE(sizeof(::ucred));
       
  1673     }
       
  1674 
       
  1675     for(int ii = 0; ii < a.count(); ++ii) {
       
  1676         const QUnixSocketRights & r = a.at(ii);
       
  1677 
       
  1678         if(r.isValid()) {
       
  1679             h->cmsg_len = CMSG_LEN(sizeof(int));
       
  1680             h->cmsg_level = SOL_SOCKET;
       
  1681             h->cmsg_type = SCM_RIGHTS;
       
  1682             *((int *)CMSG_DATA(h)) = r.peekFd();
       
  1683             h = CMSG_NXTHDR(&sendmessage, h);
       
  1684         } else {
       
  1685             sendmessage.msg_controllen -= CMSG_SPACE(sizeof(int));
       
  1686         }
       
  1687     }
       
  1688 
       
  1689 #ifdef QUNIXSOCKET_DEBUG
       
  1690     qDebug() << "QUnixSocket: Transmitting message (length" << m.d->size() << ')';
       
  1691 #endif
       
  1692     ::ssize_t s = ::sendmsg(fd, &sendmessage, MSG_DONTWAIT | MSG_NOSIGNAL);
       
  1693 #ifdef QUNIXSOCKET_DEBUG
       
  1694     qDebug() << "QUnixSocket: Transmitted message (" << s << ')';
       
  1695 #endif
       
  1696 
       
  1697     if(-1 == s) {
       
  1698         if(EAGAIN == errno || EWOULDBLOCK == errno || EINTR == errno) {
       
  1699             writeNotifier->setEnabled(true);
       
  1700         } else if(EPIPE == errno) {
       
  1701 #ifdef QUNIXSOCKET_DEBUG
       
  1702             qDebug() << "QUnixSocket: Remote side disconnected during transmit "
       
  1703                         "(" << ::strerror(errno) << ')';
       
  1704 #endif
       
  1705             me->abort();
       
  1706         } else {
       
  1707 #ifdef QUNIXSOCKET_DEBUG
       
  1708             qDebug() << "QUnixSocket: Unable to transmit data ("
       
  1709                      << ::strerror(errno) << ')';
       
  1710 #endif
       
  1711             error = (QUnixSocket::SocketError)(QUnixSocket::WriteFailure |
       
  1712                     CausedAbort);
       
  1713             me->abort();
       
  1714         }
       
  1715     } else if(s != m.d->size()) {
       
  1716 
       
  1717         // A partial transmission
       
  1718         writeNotifier->setEnabled(true);
       
  1719         delete [] (char *)sendmessage.msg_control;
       
  1720         m.d->rights = QList<QUnixSocketRights>();
       
  1721         m.d->removeBytes( s );
       
  1722         writeQueueBytes -= s;
       
  1723         emit bytesWritten(s);
       
  1724         return s;
       
  1725 
       
  1726     } else {
       
  1727 
       
  1728         // Success!
       
  1729         writeQueue.dequeue();
       
  1730         Q_ASSERT(writeQueueBytes >= (unsigned)s);
       
  1731         writeQueueBytes -= s;
       
  1732         emit bytesWritten(s);
       
  1733 
       
  1734     }
       
  1735 
       
  1736     delete [] (char *)sendmessage.msg_control;
       
  1737     if(-1 != s && !writeQueue.isEmpty())
       
  1738         return writeActivated();
       
  1739     else if(QUnixSocket::ClosingState == me->state() && writeQueue.isEmpty())
       
  1740         me->abort();
       
  1741 
       
  1742     if((-1 == s) && (EAGAIN == errno || EWOULDBLOCK == errno || EINTR == errno))
       
  1743         // Return zero bytes written to indicate retry may be required
       
  1744         return 0;
       
  1745     else
       
  1746         return s;
       
  1747 }
       
  1748 
       
  1749 void QUnixSocketPrivate::readActivated()
       
  1750 {
       
  1751 #ifdef QUNIXSOCKET_DEBUG
       
  1752     qDebug() << "QUnixSocket: readActivated";
       
  1753 #endif
       
  1754     readNotifier->setEnabled(false);
       
  1755 
       
  1756     ::iovec vec;
       
  1757     vec.iov_base = dataBuffer;
       
  1758     vec.iov_len = dataBufferCapacity;
       
  1759 
       
  1760     bzero(&message, sizeof(::msghdr));
       
  1761     message.msg_iov = &vec;
       
  1762     message.msg_iovlen = 1;
       
  1763     message.msg_controllen = ancillaryBufferCapacity();
       
  1764     message.msg_control = ancillaryBuffer;
       
  1765 
       
  1766     int flags = 0;
       
  1767 #ifdef MSG_CMSG_CLOEXEC
       
  1768     flags = MSG_CMSG_CLOEXEC;
       
  1769 #endif
       
  1770 
       
  1771     int recvrv = ::recvmsg(fd, &message, flags);
       
  1772 #ifdef QUNIXSOCKET_DEBUG
       
  1773     qDebug() << "QUnixSocket: Received message (" << recvrv << ')';
       
  1774 #endif
       
  1775     if(-1 == recvrv) {
       
  1776 #ifdef QUNIXSOCKET_DEBUG
       
  1777         qDebug() << "QUnixSocket: Unable to receive data ("
       
  1778                  << ::strerror(errno) << ')';
       
  1779 #endif
       
  1780         error = (QUnixSocket::SocketError)(QUnixSocket::ReadFailure |
       
  1781                                            CausedAbort);
       
  1782         me->abort();
       
  1783     } else if(0 == recvrv) {
       
  1784         me->abort();
       
  1785     } else {
       
  1786         Q_ASSERT(recvrv);
       
  1787         Q_ASSERT((unsigned)recvrv <= dataBufferCapacity);
       
  1788         dataBufferLength = recvrv;
       
  1789         messageValid = true;
       
  1790 
       
  1791 #ifdef QUNIXSOCKET_DEBUG
       
  1792         qDebug() << "QUnixSocket: readyRead() " << dataBufferLength;
       
  1793 #endif
       
  1794         emit readyRead();
       
  1795     }
       
  1796 }
       
  1797 
       
  1798 QT_END_NAMESPACE
       
  1799 
       
  1800 #include "qunixsocket.moc"