Coverage Report

Created: 2026-04-29 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/network/socket/qlocalsocket_unix.cpp
Line
Count
Source
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#include "qlocalsocket.h"
6
#include "qlocalsocket_p.h"
7
#include "qnet_unix_p.h"
8
9
#include <sys/types.h>
10
#include <sys/socket.h>
11
#include <sys/un.h>
12
#include <unistd.h>
13
#include <fcntl.h>
14
#include <errno.h>
15
16
#include <qdir.h>
17
#include <qdeadlinetimer.h>
18
#include <qdebug.h>
19
#include <qstringconverter.h>
20
21
#ifdef Q_OS_VXWORKS
22
#  include <selectLib.h>
23
#endif
24
25
using namespace std::chrono_literals;
26
27
0
#define QT_CONNECT_TIMEOUT 30000
28
29
QT_BEGIN_NAMESPACE
30
31
using namespace Qt::StringLiterals;
32
33
namespace {
34
// determine the full server path
35
static QString pathNameForConnection(const QString &connectingName,
36
                                     QLocalSocket::SocketOptions options)
37
0
{
38
0
    if (options.testFlag(QLocalSocket::AbstractNamespaceOption)
39
0
        || connectingName.startsWith(u'/')) {
40
0
        return connectingName;
41
0
    }
42
43
0
    return QDir::tempPath() + u'/' + connectingName;
44
0
}
45
46
static QLocalSocket::SocketOptions optionsForPlatform(QLocalSocket::SocketOptions srcOptions)
47
0
{
48
    // For OS that does not support abstract namespace the AbstractNamespaceOption
49
    // option is cleared.
50
0
    if (!PlatformSupportsAbstractNamespace)
51
0
        return QLocalSocket::NoOptions;
52
0
    return srcOptions;
53
0
}
54
}
55
56
0
QLocalSocketPrivate::QLocalSocketPrivate() : QIODevicePrivate(),
57
0
        delayConnect(nullptr),
58
0
        connectTimer(nullptr),
59
0
        connectingSocket(-1),
60
0
        state(QLocalSocket::UnconnectedState),
61
0
        socketOptions(QLocalSocket::NoOptions)
62
0
{
63
0
}
64
65
void QLocalSocketPrivate::init()
66
0
{
67
0
    Q_Q(QLocalSocket);
68
    // QIODevice signals
69
0
    q->connect(&unixSocket, SIGNAL(bytesWritten(qint64)),
70
0
               q, SIGNAL(bytesWritten(qint64)));
71
0
    q->connect(&unixSocket, SIGNAL(channelBytesWritten(int, qint64)),
72
0
               q, SIGNAL(channelBytesWritten(int, qint64)));
73
0
    q->connect(&unixSocket, SIGNAL(readyRead()), q, SIGNAL(readyRead()));
74
0
    q->connect(&unixSocket, SIGNAL(channelReadyRead(int)),
75
0
               q, SIGNAL(channelReadyRead(int)));
76
    // QAbstractSocket signals
77
0
    q->connect(&unixSocket, SIGNAL(connected()), q, SIGNAL(connected()));
78
0
    q->connect(&unixSocket, SIGNAL(disconnected()), q, SIGNAL(disconnected()));
79
0
    q->connect(&unixSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
80
0
               q, SLOT(_q_stateChanged(QAbstractSocket::SocketState)));
81
0
    q->connect(&unixSocket, SIGNAL(errorOccurred(QAbstractSocket::SocketError)),
82
0
               q, SLOT(_q_errorOccurred(QAbstractSocket::SocketError)));
83
0
    q->connect(&unixSocket, SIGNAL(readChannelFinished()), q, SIGNAL(readChannelFinished()));
84
0
    unixSocket.setParent(q);
85
0
}
86
87
void QLocalSocketPrivate::_q_errorOccurred(QAbstractSocket::SocketError socketError)
88
0
{
89
0
    Q_Q(QLocalSocket);
90
0
    QString function = "QLocalSocket"_L1;
91
0
    QLocalSocket::LocalSocketError error = (QLocalSocket::LocalSocketError)socketError;
92
0
    QString errorString = generateErrorString(error, function);
93
0
    q->setErrorString(errorString);
94
0
    emit q->errorOccurred(error);
95
0
}
96
97
void QLocalSocketPrivate::_q_stateChanged(QAbstractSocket::SocketState newState)
98
0
{
99
0
    Q_Q(QLocalSocket);
100
0
    QLocalSocket::LocalSocketState currentState = state;
101
0
    switch(newState) {
102
0
    case QAbstractSocket::UnconnectedState:
103
0
        state = QLocalSocket::UnconnectedState;
104
0
        serverName.clear();
105
0
        fullServerName.clear();
106
0
        break;
107
0
    case QAbstractSocket::ConnectingState:
108
0
        state = QLocalSocket::ConnectingState;
109
0
        break;
110
0
    case QAbstractSocket::ConnectedState:
111
0
        state = QLocalSocket::ConnectedState;
112
0
        break;
113
0
    case QAbstractSocket::ClosingState:
114
0
        state = QLocalSocket::ClosingState;
115
0
        break;
116
0
    default:
117
#if defined QLOCALSOCKET_DEBUG
118
        qWarning() << "QLocalSocket::Unhandled socket state change:" << newState;
119
#endif
120
0
        return;
121
0
    }
122
0
    if (currentState != state)
123
0
        emit q->stateChanged(state);
124
0
}
125
126
QString QLocalSocketPrivate::generateErrorString(QLocalSocket::LocalSocketError error, const QString &function) const
127
0
{
128
0
    QString errorString;
129
0
    switch (error) {
130
0
    case QLocalSocket::ConnectionRefusedError:
131
0
        errorString = QLocalSocket::tr("%1: Connection refused").arg(function);
132
0
        break;
133
0
    case QLocalSocket::PeerClosedError:
134
0
        errorString = QLocalSocket::tr("%1: Remote closed").arg(function);
135
0
        break;
136
0
    case QLocalSocket::ServerNotFoundError:
137
0
        errorString = QLocalSocket::tr("%1: Invalid name").arg(function);
138
0
        break;
139
0
    case QLocalSocket::SocketAccessError:
140
0
        errorString = QLocalSocket::tr("%1: Socket access error").arg(function);
141
0
        break;
142
0
    case QLocalSocket::SocketResourceError:
143
0
        errorString = QLocalSocket::tr("%1: Socket resource error").arg(function);
144
0
        break;
145
0
    case QLocalSocket::SocketTimeoutError:
146
0
        errorString = QLocalSocket::tr("%1: Socket operation timed out").arg(function);
147
0
        break;
148
0
    case QLocalSocket::DatagramTooLargeError:
149
0
        errorString = QLocalSocket::tr("%1: Datagram too large").arg(function);
150
0
        break;
151
0
    case QLocalSocket::ConnectionError:
152
0
        errorString = QLocalSocket::tr("%1: Connection error").arg(function);
153
0
        break;
154
0
    case QLocalSocket::UnsupportedSocketOperationError:
155
0
        errorString = QLocalSocket::tr("%1: The socket operation is not supported").arg(function);
156
0
        break;
157
0
    case QLocalSocket::OperationError:
158
0
        errorString = QLocalSocket::tr("%1: Operation not permitted when socket is in this state").arg(function);
159
0
        break;
160
0
    case QLocalSocket::UnknownSocketError:
161
0
    default:
162
0
        errorString = QLocalSocket::tr("%1: Unknown error %2").arg(function).arg(errno);
163
0
    }
164
0
    return errorString;
165
0
}
166
167
void QLocalSocketPrivate::setErrorAndEmit(QLocalSocket::LocalSocketError error, const QString &function)
168
0
{
169
0
    Q_Q(QLocalSocket);
170
0
    switch (error) {
171
0
    case QLocalSocket::ConnectionRefusedError:
172
0
        unixSocket.setSocketError(QAbstractSocket::ConnectionRefusedError);
173
0
        break;
174
0
    case QLocalSocket::PeerClosedError:
175
0
        unixSocket.setSocketError(QAbstractSocket::RemoteHostClosedError);
176
0
        break;
177
0
    case QLocalSocket::ServerNotFoundError:
178
0
        unixSocket.setSocketError(QAbstractSocket::HostNotFoundError);
179
0
        break;
180
0
    case QLocalSocket::SocketAccessError:
181
0
        unixSocket.setSocketError(QAbstractSocket::SocketAccessError);
182
0
        break;
183
0
    case QLocalSocket::SocketResourceError:
184
0
        unixSocket.setSocketError(QAbstractSocket::SocketResourceError);
185
0
        break;
186
0
    case QLocalSocket::SocketTimeoutError:
187
0
        unixSocket.setSocketError(QAbstractSocket::SocketTimeoutError);
188
0
        break;
189
0
    case QLocalSocket::DatagramTooLargeError:
190
0
        unixSocket.setSocketError(QAbstractSocket::DatagramTooLargeError);
191
0
        break;
192
0
    case QLocalSocket::ConnectionError:
193
0
        unixSocket.setSocketError(QAbstractSocket::NetworkError);
194
0
        break;
195
0
    case QLocalSocket::UnsupportedSocketOperationError:
196
0
        unixSocket.setSocketError(QAbstractSocket::UnsupportedSocketOperationError);
197
0
        break;
198
0
    case QLocalSocket::UnknownSocketError:
199
0
    default:
200
0
        unixSocket.setSocketError(QAbstractSocket::UnknownSocketError);
201
0
    }
202
203
0
    QString errorString = generateErrorString(error, function);
204
0
    q->setErrorString(errorString);
205
0
    emit q->errorOccurred(error);
206
207
    // errors cause a disconnect
208
0
    unixSocket.setSocketState(QAbstractSocket::UnconnectedState);
209
0
    bool stateChanged = (state != QLocalSocket::UnconnectedState);
210
0
    state = QLocalSocket::UnconnectedState;
211
0
    q->close();
212
0
    if (stateChanged)
213
0
        q->emit stateChanged(state);
214
0
}
215
216
void QLocalSocket::connectToServer(OpenMode openMode)
217
0
{
218
0
    Q_D(QLocalSocket);
219
0
    if (state() == ConnectedState || state() == ConnectingState) {
220
0
        QString errorString = d->generateErrorString(QLocalSocket::OperationError, "QLocalSocket::connectToserver"_L1);
221
0
        setErrorString(errorString);
222
0
        emit errorOccurred(QLocalSocket::OperationError);
223
0
        return;
224
0
    }
225
226
0
    d->errorString.clear();
227
0
    d->unixSocket.setSocketState(QAbstractSocket::ConnectingState);
228
0
    d->state = ConnectingState;
229
0
    emit stateChanged(d->state);
230
231
0
    if (d->serverName.isEmpty()) {
232
0
        d->setErrorAndEmit(ServerNotFoundError, "QLocalSocket::connectToServer"_L1);
233
0
        return;
234
0
    }
235
236
    // create the socket
237
0
    if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0, O_NONBLOCK))) {
238
0
        d->setErrorAndEmit(UnsupportedSocketOperationError, "QLocalSocket::connectToServer"_L1);
239
0
        return;
240
0
    }
241
242
    // _q_connectToSocket does the actual connecting
243
0
    d->connectingName = d->serverName;
244
0
    d->connectingOpenMode = openMode;
245
0
    d->_q_connectToSocket();
246
0
    return;
247
0
}
248
249
/*!
250
    \internal
251
252
    Tries to connect connectingName and connectingOpenMode
253
254
    \sa connectToServer(), waitForConnected()
255
  */
256
void QLocalSocketPrivate::_q_connectToSocket()
257
0
{
258
0
    Q_Q(QLocalSocket);
259
260
0
    QLocalSocket::SocketOptions options = optionsForPlatform(socketOptions);
261
0
    const QString connectingPathName = pathNameForConnection(connectingName, options);
262
0
    const QByteArray encodedConnectingPathName = QFile::encodeName(connectingPathName);
263
0
    struct ::sockaddr_un addr;
264
0
    addr.sun_family = PF_UNIX;
265
0
    memset(addr.sun_path, 0, sizeof(addr.sun_path));
266
267
    // for abstract socket add 2 to length, to take into account trailing AND leading null
268
0
    constexpr unsigned int extraCharacters = PlatformSupportsAbstractNamespace ? 2 : 1;
269
270
0
    if (sizeof(addr.sun_path) < static_cast<size_t>(encodedConnectingPathName.size() + extraCharacters)) {
271
0
        QString function = "QLocalSocket::connectToServer"_L1;
272
0
        setErrorAndEmit(QLocalSocket::ServerNotFoundError, function);
273
0
        return;
274
0
    }
275
276
0
    QT_SOCKLEN_T addrSize = sizeof(::sockaddr_un);
277
0
    if (options.testFlag(QLocalSocket::AbstractNamespaceOption)) {
278
0
        ::memcpy(addr.sun_path + 1, encodedConnectingPathName.constData(),
279
0
                 encodedConnectingPathName.size() + 1);
280
0
        addrSize = offsetof(::sockaddr_un, sun_path) + encodedConnectingPathName.size() + 1;
281
0
    } else {
282
0
        ::memcpy(addr.sun_path, encodedConnectingPathName.constData(),
283
0
                 encodedConnectingPathName.size() + 1);
284
0
    }
285
0
    if (-1 == qt_safe_connect(connectingSocket, (struct sockaddr *)&addr, addrSize)) {
286
0
        QString function = "QLocalSocket::connectToServer"_L1;
287
0
        switch (errno)
288
0
        {
289
0
        case EINVAL:
290
0
        case ECONNREFUSED:
291
0
            setErrorAndEmit(QLocalSocket::ConnectionRefusedError, function);
292
0
            break;
293
0
        case ENOENT:
294
0
            setErrorAndEmit(QLocalSocket::ServerNotFoundError, function);
295
0
            break;
296
0
        case EACCES:
297
0
        case EPERM:
298
0
            setErrorAndEmit(QLocalSocket::SocketAccessError, function);
299
0
            break;
300
0
        case ETIMEDOUT:
301
0
            setErrorAndEmit(QLocalSocket::SocketTimeoutError, function);
302
0
            break;
303
0
        case EAGAIN:
304
            // Try again later, all of the sockets listening are full
305
0
            if (!delayConnect) {
306
0
                delayConnect = new QSocketNotifier(connectingSocket, QSocketNotifier::Write, q);
307
0
                q->connect(delayConnect, SIGNAL(activated(QSocketDescriptor)), q, SLOT(_q_connectToSocket()));
308
0
            }
309
0
            if (!connectTimer) {
310
0
                connectTimer = new QTimer(q);
311
0
                q->connect(connectTimer, SIGNAL(timeout()),
312
0
                                 q, SLOT(_q_abortConnectionAttempt()),
313
0
                                 Qt::DirectConnection);
314
0
                connectTimer->start(QT_CONNECT_TIMEOUT);
315
0
            }
316
0
            delayConnect->setEnabled(true);
317
0
            break;
318
0
        default:
319
0
            setErrorAndEmit(QLocalSocket::UnknownSocketError, function);
320
0
        }
321
0
        return;
322
0
    }
323
324
    // connected!
325
0
    cancelDelayedConnect();
326
327
0
    serverName = connectingName;
328
0
    fullServerName = connectingPathName;
329
0
    if (unixSocket.setSocketDescriptor(connectingSocket,
330
0
        QAbstractSocket::ConnectedState, connectingOpenMode)) {
331
0
        q->QIODevice::open(connectingOpenMode);
332
0
        q->emit connected();
333
0
    } else {
334
0
        QString function = "QLocalSocket::connectToServer"_L1;
335
0
        setErrorAndEmit(QLocalSocket::UnknownSocketError, function);
336
0
    }
337
0
    connectingSocket = -1;
338
0
    connectingName.clear();
339
0
    connectingOpenMode = { };
340
0
}
341
342
bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor,
343
        LocalSocketState socketState, OpenMode openMode)
344
0
{
345
0
    Q_D(QLocalSocket);
346
0
    QAbstractSocket::SocketState newSocketState = QAbstractSocket::UnconnectedState;
347
0
    switch (socketState) {
348
0
    case ConnectingState:
349
0
        newSocketState = QAbstractSocket::ConnectingState;
350
0
        break;
351
0
    case ConnectedState:
352
0
        newSocketState = QAbstractSocket::ConnectedState;
353
0
        break;
354
0
    case ClosingState:
355
0
        newSocketState = QAbstractSocket::ClosingState;
356
0
        break;
357
0
    case UnconnectedState:
358
0
        newSocketState = QAbstractSocket::UnconnectedState;
359
0
        break;
360
0
    }
361
0
    QIODevice::open(openMode);
362
0
    d->state = socketState;
363
0
    d->describeSocket(socketDescriptor);
364
0
    const bool result = d->unixSocket.setSocketDescriptor(socketDescriptor,
365
0
                                                          newSocketState, openMode);
366
    // Since we directly assigned d->state above, any emission from unixSocket for
367
    // state change emission is ignored because the state hasn't changed. So, we
368
    // emit it directly here ourselves.
369
0
    if (result)
370
0
        emit stateChanged(d->state);
371
0
    return result;
372
0
}
373
374
void QLocalSocketPrivate::describeSocket(qintptr socketDescriptor)
375
0
{
376
0
    bool abstractAddress = false;
377
378
0
    struct ::sockaddr_un addr;
379
0
    QT_SOCKLEN_T len = sizeof(addr);
380
0
    memset(&addr, 0, sizeof(addr));
381
0
    const int getpeernameStatus = ::getpeername(socketDescriptor, (sockaddr *)&addr, &len);
382
0
    if (getpeernameStatus != 0 || len == offsetof(sockaddr_un, sun_path)) {
383
        // this is the case when we call it from QLocalServer, then there is no peername
384
0
        len = sizeof(addr);
385
0
        if (::getsockname(socketDescriptor, (sockaddr *)&addr, &len) != 0)
386
0
            return;
387
0
    }
388
0
    if (parseSockaddr(addr, static_cast<uint>(len), fullServerName, serverName, abstractAddress)) {
389
0
        QLocalSocket::SocketOptions options = socketOptions.value();
390
0
        socketOptions = options.setFlag(QLocalSocket::AbstractNamespaceOption, abstractAddress);
391
0
    }
392
0
}
393
394
bool QLocalSocketPrivate::parseSockaddr(const struct ::sockaddr_un &addr,
395
                                        uint len,
396
                                        QString &fullServerName,
397
                                        QString &serverName,
398
                                        bool &abstractNamespace)
399
0
{
400
0
    if (len <= offsetof(::sockaddr_un, sun_path))
401
0
        return false;
402
0
    len -= offsetof(::sockaddr_un, sun_path);
403
    // check for abstract socket address
404
0
    abstractNamespace = PlatformSupportsAbstractNamespace
405
0
                                 && (addr.sun_family == PF_UNIX && addr.sun_path[0] == 0);
406
0
    QStringDecoder toUtf16(QStringDecoder::System, QStringDecoder::Flag::Stateless);
407
    // An abstract socket address can be arbitrary binary. To properly handle such a case,
408
    // we'd have to add new access functions for this very specific case. Instead, we just
409
    // attempt to decode it according to OS text encoding. If it fails we ignore the result.
410
0
    QByteArrayView textData(addr.sun_path + (abstractNamespace ? 1 : 0),
411
0
                            len - (abstractNamespace ? 1 : 0));
412
0
    QString name = toUtf16(textData);
413
0
    if (!name.isEmpty() && !toUtf16.hasError()) {
414
        //conversion encodes the trailing zeros. So, in case of non-abstract namespace we
415
        //chop them off as \0 character is not allowed in filenames
416
0
        if (!abstractNamespace && (name.at(name.size() - 1) == QChar::fromLatin1('\0'))) {
417
0
            int truncPos = name.size() - 1;
418
0
            while (truncPos > 0 && name.at(truncPos - 1) == QChar::fromLatin1('\0'))
419
0
                truncPos--;
420
0
            name.truncate(truncPos);
421
0
        }
422
0
        fullServerName = name;
423
0
        serverName = abstractNamespace
424
0
                     ? name
425
0
                     : fullServerName.mid(fullServerName.lastIndexOf(u'/') + 1);
426
0
        if (serverName.isEmpty())
427
0
            serverName = fullServerName;
428
0
    }
429
0
    return true;
430
0
}
431
432
void QLocalSocketPrivate::_q_abortConnectionAttempt()
433
0
{
434
0
    Q_Q(QLocalSocket);
435
0
    q->close();
436
0
}
437
438
void QLocalSocketPrivate::cancelDelayedConnect()
439
0
{
440
0
    if (delayConnect) {
441
0
        delayConnect->setEnabled(false);
442
0
        delete delayConnect;
443
0
        delayConnect = nullptr;
444
0
        connectTimer->stop();
445
0
        delete connectTimer;
446
0
        connectTimer = nullptr;
447
0
    }
448
0
}
449
450
qintptr QLocalSocket::socketDescriptor() const
451
0
{
452
0
    Q_D(const QLocalSocket);
453
0
    return d->unixSocket.socketDescriptor();
454
0
}
455
456
qint64 QLocalSocket::readData(char *data, qint64 c)
457
0
{
458
0
    Q_D(QLocalSocket);
459
0
    return d->unixSocket.read(data, c);
460
0
}
461
462
qint64 QLocalSocket::readLineData(char *data, qint64 maxSize)
463
0
{
464
0
    if (!maxSize)
465
0
        return 0;
466
467
    // QIODevice::readLine() reserves space for the trailing '\0' byte,
468
    // so we must read 'maxSize + 1' bytes.
469
0
    return d_func()->unixSocket.readLine(data, maxSize + 1);
470
0
}
471
472
qint64 QLocalSocket::skipData(qint64 maxSize)
473
0
{
474
0
    return d_func()->unixSocket.skip(maxSize);
475
0
}
476
477
qint64 QLocalSocket::writeData(const char *data, qint64 c)
478
0
{
479
0
    Q_D(QLocalSocket);
480
0
    return d->unixSocket.writeData(data, c);
481
0
}
482
483
void QLocalSocket::abort()
484
0
{
485
0
    Q_D(QLocalSocket);
486
0
    d->unixSocket.abort();
487
0
    close();
488
0
}
489
490
qint64 QLocalSocket::bytesAvailable() const
491
0
{
492
0
    Q_D(const QLocalSocket);
493
0
    return QIODevice::bytesAvailable() + d->unixSocket.bytesAvailable();
494
0
}
495
496
qint64 QLocalSocket::bytesToWrite() const
497
0
{
498
0
    Q_D(const QLocalSocket);
499
0
    return d->unixSocket.bytesToWrite();
500
0
}
501
502
bool QLocalSocket::canReadLine() const
503
0
{
504
0
    Q_D(const QLocalSocket);
505
0
    return QIODevice::canReadLine() || d->unixSocket.canReadLine();
506
0
}
507
508
void QLocalSocket::close()
509
0
{
510
0
    Q_D(QLocalSocket);
511
512
0
    QIODevice::close();
513
0
    d->unixSocket.close();
514
0
    d->cancelDelayedConnect();
515
0
    if (d->connectingSocket != -1)
516
0
        ::close(d->connectingSocket);
517
0
    d->connectingSocket = -1;
518
0
    d->connectingName.clear();
519
0
    d->connectingOpenMode = { };
520
0
    d->serverName.clear();
521
0
    d->fullServerName.clear();
522
0
}
523
524
bool QLocalSocket::waitForBytesWritten(int msecs)
525
0
{
526
0
    Q_D(QLocalSocket);
527
0
    return d->unixSocket.waitForBytesWritten(msecs);
528
0
}
529
530
bool QLocalSocket::flush()
531
0
{
532
0
    Q_D(QLocalSocket);
533
0
    return d->unixSocket.flush();
534
0
}
535
536
void QLocalSocket::disconnectFromServer()
537
0
{
538
0
    Q_D(QLocalSocket);
539
0
    d->unixSocket.disconnectFromHost();
540
0
}
541
542
QLocalSocket::LocalSocketError QLocalSocket::error() const
543
0
{
544
0
    Q_D(const QLocalSocket);
545
0
    switch (d->unixSocket.error()) {
546
0
    case QAbstractSocket::ConnectionRefusedError:
547
0
        return QLocalSocket::ConnectionRefusedError;
548
0
    case QAbstractSocket::RemoteHostClosedError:
549
0
        return QLocalSocket::PeerClosedError;
550
0
    case QAbstractSocket::HostNotFoundError:
551
0
        return QLocalSocket::ServerNotFoundError;
552
0
    case QAbstractSocket::SocketAccessError:
553
0
        return QLocalSocket::SocketAccessError;
554
0
    case QAbstractSocket::SocketResourceError:
555
0
        return QLocalSocket::SocketResourceError;
556
0
    case QAbstractSocket::SocketTimeoutError:
557
0
        return QLocalSocket::SocketTimeoutError;
558
0
    case QAbstractSocket::DatagramTooLargeError:
559
0
        return QLocalSocket::DatagramTooLargeError;
560
0
    case QAbstractSocket::NetworkError:
561
0
        return QLocalSocket::ConnectionError;
562
0
    case QAbstractSocket::UnsupportedSocketOperationError:
563
0
        return QLocalSocket::UnsupportedSocketOperationError;
564
0
    case QAbstractSocket::UnknownSocketError:
565
0
        return QLocalSocket::UnknownSocketError;
566
0
    default:
567
#if defined QLOCALSOCKET_DEBUG
568
        qWarning() << "QLocalSocket error not handled:" << d->unixSocket.error();
569
#endif
570
0
        break;
571
0
    }
572
0
    return UnknownSocketError;
573
0
}
574
575
bool QLocalSocket::isValid() const
576
0
{
577
0
    Q_D(const QLocalSocket);
578
0
    return d->unixSocket.isValid();
579
0
}
580
581
qint64 QLocalSocket::readBufferSize() const
582
0
{
583
0
    Q_D(const QLocalSocket);
584
0
    return d->unixSocket.readBufferSize();
585
0
}
586
587
void QLocalSocket::setReadBufferSize(qint64 size)
588
0
{
589
0
    Q_D(QLocalSocket);
590
0
    d->unixSocket.setReadBufferSize(size);
591
0
}
592
593
bool QLocalSocket::waitForConnected(int msec)
594
0
{
595
0
    Q_D(QLocalSocket);
596
597
0
    if (state() != ConnectingState)
598
0
        return (state() == ConnectedState);
599
600
0
    pollfd pfd = qt_make_pollfd(d->connectingSocket, POLLIN);
601
602
0
    QDeadlineTimer deadline{msec};
603
0
    auto remainingTime = deadline.remainingTimeAsDuration();
604
605
0
    do {
606
0
        const int result = qt_safe_poll(&pfd, 1, deadline);
607
0
        if (result == -1)
608
0
            d->setErrorAndEmit(QLocalSocket::UnknownSocketError,
609
0
                               "QLocalSocket::waitForConnected"_L1);
610
0
        else if (result > 0)
611
0
            d->_q_connectToSocket();
612
0
    } while (state() == ConnectingState
613
0
             && (remainingTime = deadline.remainingTimeAsDuration()) > 0ns);
614
615
0
    return (state() == ConnectedState);
616
0
}
617
618
bool QLocalSocket::waitForDisconnected(int msecs)
619
0
{
620
0
    Q_D(QLocalSocket);
621
0
    if (state() == UnconnectedState) {
622
0
        qWarning("QLocalSocket::waitForDisconnected() is not allowed in UnconnectedState");
623
0
        return false;
624
0
    }
625
0
    return (d->unixSocket.waitForDisconnected(msecs));
626
0
}
627
628
bool QLocalSocket::waitForReadyRead(int msecs)
629
0
{
630
0
    Q_D(QLocalSocket);
631
0
    if (state() == QLocalSocket::UnconnectedState)
632
0
        return false;
633
0
    return (d->unixSocket.waitForReadyRead(msecs));
634
0
}
635
636
QT_END_NAMESPACE