save errno before calling any other function in QLocalServerPrivate::setError()

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-12-31 08:49:17 +02:00
parent ea280c9597
commit 602ff4fab3
3 changed files with 41 additions and 34 deletions

View file

@ -3,7 +3,7 @@
# https://wiki.archlinux.org/index.php/Arch_package_guidelines
pkgname=katie-git
pkgver=4.13.0.r7914.209834030
pkgver=4.13.0.r7921.ea280c959
pkgrel=1
pkgdesc='C++ toolkit derived from the Qt 4.8 framework'
arch=('i486' 'i686' 'pentium4' 'x86_64' 'arm')

View file

@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE
\sa listen()
*/
QLocalServer::QLocalServer(QObject *parent)
: QObject(*new QLocalServerPrivate, parent)
: QObject(*new QLocalServerPrivate, parent)
{
}
@ -82,8 +82,9 @@ QLocalServer::QLocalServer(QObject *parent)
*/
QLocalServer::~QLocalServer()
{
if (isListening())
if (isListening()) {
close();
}
}
/*!
@ -95,8 +96,9 @@ QLocalServer::~QLocalServer()
void QLocalServer::close()
{
Q_D(QLocalServer);
if (!isListening())
if (!isListening()) {
return;
}
qDeleteAll(d->pendingConnections);
d->pendingConnections.clear();
d->closeServer();
@ -246,11 +248,13 @@ int QLocalServer::maxPendingConnections() const
QLocalSocket *QLocalServer::nextPendingConnection()
{
Q_D(QLocalServer);
if (d->pendingConnections.isEmpty())
return 0;
if (d->pendingConnections.isEmpty()) {
return nullptr;
}
QLocalSocket *nextSocket = d->pendingConnections.dequeue();
if (d->pendingConnections.size() <= d->maxPendingConnections)
if (d->pendingConnections.size() <= d->maxPendingConnections) {
d->socketNotifier->setEnabled(true);
}
return nextSocket;
}
@ -346,11 +350,13 @@ void QLocalServer::setMaxPendingConnections(int numConnections)
bool QLocalServer::waitForNewConnection(int msec, bool *timedOut)
{
Q_D(QLocalServer);
if (timedOut)
if (timedOut) {
*timedOut = false;
}
if (!isListening())
if (!isListening()) {
return false;
}
d->waitForNewConnection(msec, timedOut);

View file

@ -63,7 +63,7 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
// create the unix socket
listenSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0);
if (-1 == listenSocket) {
if (listenSocket == -1) {
setError(QLatin1String("QLocalServer::listen"));
closeServer();
return false;
@ -78,12 +78,11 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
closeServer();
return false;
}
::memcpy(addr.sun_path, latinFullServerName.constData(),
latinFullServerName.size() + 1);
::memcpy(addr.sun_path, latinFullServerName.constData(), latinFullServerName.size() + 1);
// bind
if(-1 == ::bind(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un))) {
if (::bind(listenSocket, (sockaddr *)&addr, sizeof(sockaddr_un)) == -1) {
setError(QLatin1String("QLocalServer::listen"));
// if address is in use already, just close the socket, but do not delete the file
if(errno == EADDRINUSE)
@ -96,19 +95,18 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
}
// listen for connections
if (-1 == ::listen(listenSocket, SOMAXCONN)) {
if (::listen(listenSocket, SOMAXCONN) == -1) {
setError(QLatin1String("QLocalServer::listen"));
closeServer();
listenSocket = -1;
if (error != QAbstractSocket::AddressInUseError)
if (error != QAbstractSocket::AddressInUseError) {
QFile::remove(fullServerName);
}
return false;
}
Q_ASSERT(!socketNotifier);
socketNotifier = new QSocketNotifier(listenSocket,
QSocketNotifier::Read, q);
q->connect(socketNotifier, SIGNAL(activated(int)),
q, SLOT(_q_onNewConnection()));
socketNotifier = new QSocketNotifier(listenSocket, QSocketNotifier::Read, q);
q->connect(socketNotifier, SIGNAL(activated(int)), q, SLOT(_q_onNewConnection()));
socketNotifier->setEnabled(maxPendingConnections > 0);
return true;
}
@ -126,12 +124,14 @@ void QLocalServerPrivate::closeServer()
socketNotifier = 0;
}
if (-1 != listenSocket)
if (listenSocket != -1) {
qt_safe_close(listenSocket);
}
listenSocket = -1;
if (!fullServerName.isEmpty())
if (!fullServerName.isEmpty()) {
QFile::remove(fullServerName);
}
}
/*!
@ -143,18 +143,18 @@ void QLocalServerPrivate::closeServer()
void QLocalServerPrivate::_q_onNewConnection()
{
Q_Q(QLocalServer);
if (-1 == listenSocket)
if (listenSocket == -1) {
return;
}
::sockaddr_un addr;
QT_SOCKLEN_T length = sizeof(sockaddr_un);
int connectedSocket = qt_safe_accept(listenSocket, (sockaddr *)&addr, &length);
if(-1 == connectedSocket) {
if (connectedSocket == -1) {
setError(QLatin1String("QLocalSocket::activated"));
closeServer();
} else {
socketNotifier->setEnabled(pendingConnections.size()
<= maxPendingConnections);
socketNotifier->setEnabled(pendingConnections.size() <= maxPendingConnections);
q->incomingConnection(connectedSocket);
}
}
@ -165,23 +165,27 @@ void QLocalServerPrivate::waitForNewConnection(int msec, bool *timedOut)
::memset(&fds, 0, sizeof(struct pollfd));
fds.fd = listenSocket;
fds.events = POLLIN;
int result = qt_safe_poll(&fds, msec);
const int result = qt_safe_poll(&fds, msec);
if (result == -1) {
setError(QLatin1String("QLocalServer::waitForNewConnection"));
closeServer();
}
if (result > 0)
if (result > 0) {
_q_onNewConnection();
if (timedOut)
}
if (timedOut) {
*timedOut = (result == 0);
}
}
void QLocalServerPrivate::setError(const QString &function)
{
if (EAGAIN == errno)
const int savederrno = errno;
if (EAGAIN == savederrno) {
return;
}
switch (errno) {
switch (savederrno) {
case EACCES:
errorString = QLocalServer::tr("%1: Permission denied").arg(function);
error = QAbstractSocket::SocketAccessError;
@ -200,8 +204,7 @@ void QLocalServerPrivate::setError(const QString &function)
break;
default:
errorString = QLocalServer::tr("%1: Unknown error %2")
.arg(function).arg(errno);
errorString = QLocalServer::tr("%1: Unknown error %2").arg(function).arg(savederrno);
error = QAbstractSocket::UnknownSocketError;
#if defined QLOCALSERVER_DEBUG
qWarning() << errorString << "fullServerName:" << fullServerName;
@ -212,5 +215,3 @@ void QLocalServerPrivate::setError(const QString &function)
QT_END_NAMESPACE
#endif // QT_NO_LOCALSERVER