/*!
    \internal

    Setup unix_key
 */
key_t QSystemLockPrivate::handle()
{
    if (key.isEmpty())
        return -1;

    // ftok requires that an actual file exists somewhere
    // If we have already made at some point in the past,
    // double check that it is still there.
    if (-1 != unix_key) {
        int aNewunix_key = ftok(QFile::encodeName(fileName).constData(), 'Q');
        if (aNewunix_key != unix_key) {
            cleanHandle();
        } else {
            return unix_key;
        }
    }

    // Create the file needed for ftok
#if defined(Q_OS_SYMBIAN)
    int built = createUnixKeyFile(fileName);
#else
    int built = QSharedMemoryPrivate::createUnixKeyFile(fileName);
#endif
    if (-1 == built)
        return -1;
    createdFile = (1 == built);

    // Get the unix key for the created file
    unix_key = ftok(QFile::encodeName(fileName).constData(), 'Q');
    if (-1 == unix_key) {
        setErrorString(QLatin1String("QSystemLock::handle ftok"));
        return -1;
    }

    // Get semaphore
    semaphore = semget(unix_key, 1, 0666 | IPC_CREAT | IPC_EXCL);
    if (-1 == semaphore) {
        if (errno == EEXIST)
            semaphore = semget(unix_key, 1, 0666 | IPC_CREAT);
        if (-1 == semaphore) {
            setErrorString(QLatin1String("QSystemLock::handle semget"));
            cleanHandle();
            return -1;
        }
    } else {
        // Created semaphore, initialize value.
        createdSemaphore = true;
        qt_semun init_op;
        init_op.val = MAX_LOCKS;
        if (-1 == semctl(semaphore, 0, SETVAL, init_op)) {
            setErrorString(QLatin1String("QSystemLock::handle semctl"));
            cleanHandle();
            return -1;
        }
    }

    return unix_key;
}
Beispiel #2
0
bool QSharedMemoryPrivate::create(int size)
{
    // build file if needed
    bool createdFile = false;
    int built = createUnixKeyFile(makePlatformSafeKey(key));
    if (built == -1) {
        errorString = QSharedMemory::tr("%1: unable to make key").arg(QLatin1String("QSharedMemory::handle:"));
        error = QSharedMemory::KeyError;
        return false;
    }
    if (built == 1) {
        createdFile = true;
    }

    // get handle
    if (!handle()) {
        if (createdFile)
            QFile::remove(makePlatformSafeKey(key));
        return false;
    }

    // create
    if (-1 == shmget(unix_key, size, 0666 | IPC_CREAT | IPC_EXCL)) {
        QString function = QLatin1String("QSharedMemory::create");
        switch (errno) {
        case EINVAL:
            errorString = QSharedMemory::tr("%1: system-imposed size restrictions").arg(QLatin1String("QSharedMemory::handle"));
            error = QSharedMemory::InvalidSize;
            break;
        default:
            setErrorString(function);
        }
        if (createdFile && error != QSharedMemory::AlreadyExists)
            QFile::remove(makePlatformSafeKey(key));
        return false;
    }

    return true;
}