Make QLocalSocket connectable with open()

Add getter and setter for handling the server QLocalSocket connects to.

Move the connectServer() implementation to QLocalSocket::open
so the local socket can be handled transparently as a QIODevice

Add a convenient connectToServer(OpenMode) method

Change-Id: Ibc8dc33f79903f92daf2d1ca2e64ead2ce39f33e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Corentin Jabot 2012-11-25 17:30:15 +01:00 committed by The Qt Project
parent 866a5d0c28
commit 953255abab
5 changed files with 94 additions and 37 deletions

View File

@ -71,18 +71,17 @@ QT_BEGIN_NAMESPACE
*/
/*!
\fn void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
\fn void QLocalSocket::open(OpenMode openMode)
Attempts to make a connection to \a name.
Equivalent to connectToServer(OpenMode mode).
The socket is opened in the given \a openMode to the server defined by setServerName().
The socket is opened in the given \a openMode and first enters ConnectingState.
It then attempts to connect to the address or addresses returned by the lookup.
Finally, if a connection is established, QLocalSocket enters ConnectedState
and emits connected().
Note that unlike in most other QIODevice subclasses, open() may not open the device directly.
The function return false if the socket was already connected or if the server to connect
to was not defined and true in any other case. The connected() or error() signals will be
emitted once the device is actualy open (or the connection failed).
At any point, the socket can emit error() to signal that an error occurred.
See also state(), serverName(), and waitForConnected().
See connectToServer() for more details.
*/
/*!
@ -354,8 +353,62 @@ QLocalSocket::~QLocalSocket()
}
/*!
Returns the name of the peer as specified by connectToServer(), or an
empty QString if connectToServer() has not been called or it failed.
\since 5.1
Attempts to make a connection to serverName().
setServerName() must be called before you open the connection.
Alternatively you can use connectToServer(const QString &name, OpenMode openMode);
The socket is opened in the given \a openMode and first enters ConnectingState.
If a connection is established, QLocalSocket enters ConnectedState and emits connected().
After calling this function, the socket can emit error() to signal that an error occurred.
\sa state(), serverName(), waitForConnected()
*/
void QLocalSocket::connectToServer(OpenMode openMode)
{
open(openMode);
}
/*! \overload
Set the server \a name and attempts to make a connection to it.
The socket is opened in the given \a openMode and first enters ConnectingState.
If a connection is established, QLocalSocket enters ConnectedState and emits connected().
After calling this function, the socket can emit error() to signal that an error occurred.
\sa state(), serverName(), waitForConnected()
*/
void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
{
setServerName(name);
open(openMode);
}
/*!
\since 5.1
Set the \a name of the peer to connect to.
On Windows name is the name of a named pipe; on Unix name is the name of a local domain socket.
This function must be called when the socket is not connected.
*/
void QLocalSocket::setServerName(const QString & name)
{
Q_D(QLocalSocket);
if (d->state != UnconnectedState) {
qWarning("QLocalSocket::setServerName() called while not in unconnected state");
return;
}
d->serverName = name;
}
/*!
Returns the name of the peer as specified by setServerName(), or an
empty QString if setServerName() has not been called or connectToServer() failed.
\sa connectToServer(), fullServerName()

View File

@ -84,9 +84,11 @@ public:
QLocalSocket(QObject *parent = 0);
~QLocalSocket();
void connectToServer(OpenMode openMode = ReadWrite);
void connectToServer(const QString &name, OpenMode openMode = ReadWrite);
void disconnectFromServer();
void setServerName(const QString &name);
QString serverName() const;
QString fullServerName() const;
@ -95,6 +97,7 @@ public:
virtual qint64 bytesAvailable() const;
virtual qint64 bytesToWrite() const;
virtual bool canReadLine() const;
virtual bool open(OpenMode openMode = ReadWrite) Q_DECL_OVERRIDE;
virtual void close();
LocalSocketError error() const;
bool flush();

View File

@ -214,29 +214,28 @@ void QLocalSocketPrivate::errorOccurred(QLocalSocket::LocalSocketError error, co
q->emit stateChanged(state);
}
void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
bool QLocalSocket::open(OpenMode openMode)
{
Q_D(QLocalSocket);
if (state() == ConnectedState
|| state() == ConnectingState)
return;
if (state() == ConnectedState || state() == ConnectingState) {
return false;
}
d->errorString.clear();
d->state = ConnectingState;
emit stateChanged(d->state);
if (name.isEmpty()) {
if (d->serverName.isEmpty()) {
d->errorOccurred(ServerNotFoundError,
QLatin1String("QLocalSocket::connectToServer"));
return;
return false;
}
d->serverName = name;
const QLatin1String prefix("QLocalServer/");
if (name.startsWith(prefix))
d->fullServerName = name;
d->fullServerName = d->serverName;
else
d->fullServerName = prefix + name;
d->fullServerName = prefix + d->serverName;
QSettings settings(QLatin1String("QtProject"), QLatin1String("Qt"));
bool ok;
@ -244,10 +243,11 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
if (!ok) {
d->errorOccurred(ServerNotFoundError,
QLatin1String("QLocalSocket::connectToServer"));
return;
return false;
}
d->tcpSocket->connectToHost(QHostAddress::LocalHost, port, openMode);
QIODevice::open(openMode);
return true;
}
bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor,

View File

@ -221,14 +221,14 @@ void QLocalSocketPrivate::errorOccurred(QLocalSocket::LocalSocketError error, co
q->emit stateChanged(state);
}
void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
bool QLocalSocket::open(OpenMode openMode)
{
Q_D(QLocalSocket);
if (state() == ConnectedState || state() == ConnectingState) {
QString errorString = d->generateErrorString(QLocalSocket::OperationError, QLatin1String("QLocalSocket::connectToserver"));
setErrorString(errorString);
emit error(QLocalSocket::OperationError);
return;
return false;
}
d->errorString.clear();
@ -236,17 +236,17 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
d->state = ConnectingState;
emit stateChanged(d->state);
if (name.isEmpty()) {
if (d->serverName.isEmpty()) {
d->errorOccurred(ServerNotFoundError,
QLatin1String("QLocalSocket::connectToServer"));
return;
return false;
}
// create the socket
if (-1 == (d->connectingSocket = qt_safe_socket(PF_UNIX, SOCK_STREAM, 0))) {
d->errorOccurred(UnsupportedSocketOperationError,
QLatin1String("QLocalSocket::connectToServer"));
return;
return false;
}
// set non blocking so we can try to connect and it won't wait
int flags = fcntl(d->connectingSocket, F_GETFL, 0);
@ -254,13 +254,14 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
|| -1 == (fcntl(d->connectingSocket, F_SETFL, flags | O_NONBLOCK))) {
d->errorOccurred(UnknownSocketError,
QLatin1String("QLocalSocket::connectToServer"));
return;
return false;
}
// _q_connectToSocket does the actual connecting
d->connectingName = name;
d->connectingName = d->serverName;
d->connectingOpenMode = openMode;
d->_q_connectToSocket();
return true;
}
/*!

View File

@ -128,33 +128,33 @@ void QLocalSocketPrivate::destroyPipeHandles()
}
}
void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
bool QLocalSocket::open(OpenMode openMode)
{
Q_D(QLocalSocket);
if (state() == ConnectedState || state() == ConnectingState) {
setErrorString(tr("Trying to connect while connection is in progress"));
emit error(QLocalSocket::OperationError);
return;
return false;
}
d->error = QLocalSocket::UnknownSocketError;
d->errorString = QString();
d->state = ConnectingState;
emit stateChanged(d->state);
if (name.isEmpty()) {
if (d->serverName.isEmpty()) {
d->error = QLocalSocket::ServerNotFoundError;
setErrorString(QLocalSocket::tr("%1: Invalid name").arg(QLatin1String("QLocalSocket::connectToServer")));
d->state = UnconnectedState;
emit error(d->error);
emit stateChanged(d->state);
return;
return false;
}
QString pipePath = QLatin1String("\\\\.\\pipe\\");
if (name.startsWith(pipePath))
d->fullServerName = name;
if (d->serverName.startsWith(pipePath))
d->fullServerName = d->serverName;
else
d->fullServerName = pipePath + name;
d->fullServerName = pipePath + d->serverName;
// Try to open a named pipe
HANDLE localSocket;
forever {
@ -184,15 +184,15 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
if (localSocket == INVALID_HANDLE_VALUE) {
d->setErrorString(QLatin1String("QLocalSocket::connectToServer"));
d->fullServerName = QString();
return;
return false;
}
// we have a valid handle
d->serverName = name;
if (setSocketDescriptor((qintptr)localSocket, ConnectedState, openMode)) {
d->handle = localSocket;
emit connected();
}
return true;
}
// This is reading from the buffer