QLockFile::LockError QLockFilePrivate::tryLock_sys() { // Assemble data, to write in a single call to write // (otherwise we'd have to check every write call) // Use operator% from the fast builder to avoid multiple memory allocations. QByteArray fileData = QByteArray::number(QCoreApplication::applicationPid()) + '\n' + qAppName().toUtf8() + '\n' + localHostName().toUtf8() + '\n'; const QByteArray lockFileName = QFile::encodeName(fileName); const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0644); if (fd < 0) { switch (errno) { case EEXIST: return QLockFile::LockFailedError; case EACCES: case EROFS: return QLockFile::PermissionError; default: return QLockFile::UnknownError; } } // Ensure nobody else can delete the file while we have it if (!setNativeLocks(fd)) qWarning() << "setNativeLocks failed:" << strerror(errno); // We hold the lock, continue. fileHandle = fd; QLockFile::LockError error = QLockFile::NoError; if (qt_write_loop(fd, fileData.constData(), fileData.size()) < fileData.size()) error = QLockFile::UnknownError; // partition full return error; }
bool NetworkDevice::init() { debugAssert(! initialized); logPrintf("Network Startup"); logPrintf("Starting WinSock networking.\n"); WSADATA wsda; WSAStartup(MAKEWORD(G3D_WINSOCK_MAJOR_VERSION, G3D_WINSOCK_MINOR_VERSION), &wsda); std::string hostname = "localhost"; { char ac[128]; if (gethostname(ac, sizeof(ac)) == -1) { logPrintf("Warning: Error while getting local host name\n"); } else { hostname = gethostbyname(ac)->h_name; } } EthernetAdapter a; a.hostname = hostname; a.name = ""; a.ip = NetAddress(hostname, 0).ip(); // TODO: Find subnet on Win32 a.subnet = 0x0000FFFF; // TODO: Find broadcast on Win32 a.broadcast = 0xFFFFFFFF; // TODO: find MAC on Win32 addAdapter(a); std::string machine = localHostName(); std::string addr = NetAddress(machine, 0).ipString(); logPrintf( "Network:\n" " Status: %s\n" " Loaded winsock specification version %d (%d is " "the highest available)\n" " %d sockets available\n" " Largest UDP datagram packet size is %d bytes\n\n", wsda.szDescription, wsda.szSystemStatus, wsda.wVersion, wsda.wHighVersion, wsda.iMaxSockets, wsda.iMaxUdpDg); // TODO: WSAIoctl for subnet and broadcast addresses // http://msdn.microsoft.com/en-us/library/ms741621(VS.85).aspx // // TODO: SIO_GET_INTERFACE_LIST initialized = true; return true; }
QLockFile::LockError QLockFilePrivate::tryLock_sys() { const QFileSystemEntry fileEntry(fileName); // When writing, allow others to read. // When reading, QFile will allow others to read and write, all good. // Adding FILE_SHARE_DELETE would allow forceful deletion of stale files, // but Windows doesn't allow recreating it while this handle is open anyway, // so this would only create confusion (can't lock, but no lock file to read from). const DWORD dwShareMode = FILE_SHARE_READ; #ifndef Q_OS_WINRT SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE }; HANDLE fh = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(), GENERIC_WRITE, dwShareMode, &securityAtts, CREATE_NEW, // error if already exists FILE_ATTRIBUTE_NORMAL, NULL); #else // !Q_OS_WINRT HANDLE fh = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(), GENERIC_WRITE, dwShareMode, CREATE_NEW, // error if already exists NULL); #endif // Q_OS_WINRT if (fh == INVALID_HANDLE_VALUE) { const DWORD lastError = GetLastError(); switch (lastError) { case ERROR_SHARING_VIOLATION: case ERROR_ALREADY_EXISTS: case ERROR_FILE_EXISTS: case ERROR_ACCESS_DENIED: // readonly file, or file still in use by another process. Assume the latter, since we don't create it readonly. return QLockFile::LockFailedError; default: qWarning() << "Got unexpected locking error" << lastError; return QLockFile::UnknownError; } } // We hold the lock, continue. fileHandle = fh; // Assemble data, to write in a single call to write // (otherwise we'd have to check every write call) QByteArray fileData; fileData += QByteArray::number(QCoreApplication::applicationPid()); fileData += '\n'; fileData += qAppName().toUtf8(); fileData += '\n'; fileData += localHostName(); fileData += '\n'; DWORD bytesWritten = 0; QLockFile::LockError error = QLockFile::NoError; if (!WriteFile(fh, fileData.constData(), fileData.size(), &bytesWritten, NULL) || !FlushFileBuffers(fh)) error = QLockFile::UnknownError; // partition full return error; }
bool QLockFilePrivate::isApparentlyStale() const { qint64 pid; QString hostname, appname; if (!getLockInfo(&pid, &hostname, &appname)) return false; if (hostname.isEmpty() || hostname == localHostName()) { if (::kill(pid, 0) == -1 && errno == ESRCH) return true; // PID doesn't exist anymore } const qint64 age = QFileInfo(fileName).lastModified().secsTo(QDateTime::currentDateTime()) * 1000; return staleLockTime > 0 && age > staleLockTime; }
static const QString getCacheFilePath() { QFile machineIdFile("/var/lib/dbus/machine-id"); QString machineId; if (machineIdFile.exists()) { if (machineIdFile.open(QIODevice::ReadOnly)) machineId = QString::fromLatin1(machineIdFile.readAll().trimmed()); } if (machineId.isEmpty()) machineId = localHostName(); const QString dirPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation); if (QSysInfo::ByteOrder == QSysInfo::BigEndian) return dirPath + QLatin1String("/qt_compose_cache_big_endian_") + machineId; return dirPath + QLatin1String("/qt_compose_cache_little_endian_") + machineId; }
QLockFile::LockError QLockFilePrivate::tryLock_sys() { // Assemble data, to write in a single call to write // (otherwise we'd have to check every write call) // Use operator% from the fast builder to avoid multiple memory allocations. QByteArray fileData = QByteArray::number(QCoreApplication::applicationPid()) % '\n' % QCoreApplication::applicationName().toUtf8() % '\n' % localHostName() % '\n'; const QByteArray lockFileName = QFile::encodeName(fileName); const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY | O_CREAT | O_EXCL, 0644); if (fd < 0) { switch (errno) { case EEXIST: return QLockFile::LockFailedError; case EACCES: case EROFS: return QLockFile::PermissionError; default: return QLockFile::UnknownError; } } // Ensure nobody else can delete the file while we have it if (!setNativeLocks(fileName, fd)) { const int errnoSaved = errno; qWarning() << "setNativeLocks failed:" << qt_error_string(errnoSaved); } if (qt_write_loop(fd, fileData.constData(), fileData.size()) < fileData.size()) { close(fd); if (!QFile::remove(fileName)) qWarning("QLockFile: Could not remove our own lock file %s.", qPrintable(fileName)); return QLockFile::UnknownError; // partition full } // We hold the lock, continue. fileHandle = fd; // Sync to disk if possible. Ignore errors (e.g. not supported). #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 fdatasync(fileHandle); #else fsync(fileHandle); #endif return QLockFile::NoError; }
bool QLockFilePrivate::isApparentlyStale() const { qint64 pid; QString hostname, appname; if (getLockInfo(&pid, &hostname, &appname)) { if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { if (::kill(pid, 0) == -1 && errno == ESRCH) return true; // PID doesn't exist anymore const QString processName = processNameByPid(pid); if (!processName.isEmpty()) { QFileInfo fi(appname); if (fi.isSymLink()) fi.setFile(fi.symLinkTarget()); if (processName != fi.fileName()) return true; // PID got reused by a different application. } } } const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); return staleLockTime > 0 && age > staleLockTime; }
bool QLockFilePrivate::isApparentlyStale() const { qint64 pid; QString hostname, appname; if (!getLockInfo(&pid, &hostname, &appname)) return false; // On WinRT there seems to be no way of obtaining information about other // processes due to sandboxing #ifndef Q_OS_WINRT if (hostname == QString::fromLocal8Bit(localHostName())) { HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (!procHandle) return true; // We got a handle but check if process is still alive DWORD dwR = ::WaitForSingleObject(procHandle, 0); ::CloseHandle(procHandle); if (dwR == WAIT_TIMEOUT) return true; } #endif // !Q_OS_WINRT const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); return staleLockTime > 0 && age > staleLockTime; }
bool NetworkDevice::init(G3D::Log* _log) { debugAssert(!initialized); debugLog = _log; #ifdef G3D_WIN32 if (debugLog) { debugLog->section("Network Startup"); debugLog->println("Starting WinSock networking.\n"); } WSADATA wsda; WSAStartup(MAKEWORD(G3D_WINSOCK_MAJOR_VERSION, G3D_WINSOCK_MINOR_VERSION), &wsda); if (debugLog) { std::string machine = localHostName(); std::string addr = NetAddress(machine, 0).ipString(); debugLog->printf( "Network:\n" " localhost = %s (%s)\n" " %s\n" " Status: %s\n" " Loaded winsock specification version %d (%d is " "the highest available)\n" " %d sockets available\n" " Largest UDP datagram packet size is %d bytes\n\n", machine.c_str(), addr.c_str(), wsda.szDescription, wsda.szSystemStatus, wsda.wVersion, wsda.wHighVersion, wsda.iMaxSockets, wsda.iMaxUdpDg); } #endif if (debugLog) {debugLog->section("Testing Network");} SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (debugLog) {debugLog->print("Open Socket ");} if (sock == SOCKET_ERROR) { if (debugLog) { debugLog->println("FAIL"); debugLog->println(socketErrorCode()); } return false; } if (debugLog) { debugLog->println("Ok"); } int TR = true; int ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&TR, sizeof(TR)); if (debugLog) {debugLog->print("Enable UDP Broadcast ");} if (ret != 0) { if (debugLog) { debugLog->println("FAIL"); debugLog->println(socketErrorCode()); } return false; } if (debugLog) {debugLog->println("Ok");} if (debugLog) {debugLog->print("Testing UDP Broadcast ");} SOCKADDR_IN addr; int32 x; addr = NetAddress(0xFFFFFFFF, 23).addr; ret = sendto(sock, (const char*)&x, sizeof(x), 0, (struct sockaddr *) &addr, sizeof(addr)); if (ret == SOCKET_ERROR) { if (debugLog) { debugLog->println("FAIL"); debugLog->println(socketErrorCode()); } return false; } if (debugLog) {debugLog->println("Ok");} if (debugLog) {debugLog->section("");} initialized = true; return true; }