42 #include "qtlocalpeer.h" 43 #include <QCoreApplication> 44 #include <QDataStream> 46 #include <QLatin1String> 50 #include <qt_windows.h> 51 typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*);
52 static PProcessIdToSessionId pProcessIdToSessionId = 0;
54 #if defined(Q_OS_UNIX) 55 #include <sys/types.h> 61 #include "qtlockedfile.cpp" 63 #include "qtlockedfile_win.cpp" 65 #include "qtlockedfile_unix.cpp" 69 const char* QtLocalPeer::ack =
"ack";
71 QtLocalPeer::QtLocalPeer(QObject* parent,
const QString &appId)
72 : QObject(parent), id(appId)
76 id = QCoreApplication::applicationFilePath();
80 prefix =
id.section(QLatin1Char(
'/'), -1);
82 prefix.remove(QRegExp(QLatin1String(
"[^a-zA-Z]")));
85 QByteArray idc =
id.toUtf8();
86 quint16 idNum = qChecksum(idc.constData(), idc.size());
87 socketName = QLatin1String(
"qtsingleapp-") + prefix
88 + QLatin1Char(
'-') + QString::number(idNum, 16);
91 if (!pProcessIdToSessionId) {
92 QLibrary lib(QLatin1String(
"kernel32"));
93 pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve(
"ProcessIdToSessionId");
95 if (pProcessIdToSessionId) {
97 pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
98 socketName += QLatin1Char(
'-') + QString::number(sessionId, 16);
101 socketName += QLatin1Char(
'-') + QString::number(::getuid(), 16);
104 server =
new QLocalServer(
this);
105 QString lockName = QDir(QDir::tempPath()).absolutePath()
106 + QLatin1Char(
'/') + socketName
107 + QLatin1String(
"-lockfile");
108 lockFile.setFileName(lockName);
109 lockFile.open(QIODevice::ReadWrite);
114 bool QtLocalPeer::isClient()
116 if (lockFile.isLocked())
119 if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock,
false))
122 bool res = server->listen(socketName);
123 #if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) 125 if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
126 QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char(
'/')+socketName);
127 res = server->listen(socketName);
131 qWarning(
"QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
132 QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
137 bool QtLocalPeer::sendMessage(
const QString &message,
int timeout)
144 for(
int i = 0; i < 2; i++) {
146 socket.connectToServer(socketName);
147 connOk = socket.waitForConnected(timeout/2);
151 #if defined(Q_OS_WIN) 154 struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
155 nanosleep(&ts, NULL);
161 QByteArray uMsg(message.toUtf8());
162 QDataStream ds(&socket);
163 ds.writeBytes(uMsg.constData(), uMsg.size());
164 bool res = socket.waitForBytesWritten(timeout);
166 res &= socket.waitForReadyRead(timeout);
168 res &= (socket.read(qstrlen(ack)) == ack);
174 void QtLocalPeer::receiveConnection()
176 QLocalSocket* socket = server->nextPendingConnection();
181 if (socket->state() == QLocalSocket::UnconnectedState) {
182 qWarning(
"QtLocalPeer: Peer disconnected");
186 if (socket->bytesAvailable() >= qint64(
sizeof(quint32)))
188 socket->waitForReadyRead();
191 QDataStream ds(socket);
195 uMsg.resize(remaining);
197 char* uMsgBuf = uMsg.data();
199 got = ds.readRawData(uMsgBuf, remaining);
202 }
while (remaining && got >= 0 && socket->waitForReadyRead(2000));
204 qWarning(
"QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
208 QString message(QString::fromUtf8(uMsg));
209 socket->write(ack, qstrlen(ack));
210 socket->waitForBytesWritten(1000);
211 socket->waitForDisconnected(1000);
213 emit messageReceived(message);