/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsharedmemory.h"
#include "qsharedmemory_p.h"
#include "qsystemsemaphore.h"
#include <qdir.h>
#include <qcryptographichash.h>
#include <qdebug.h>
#ifdef Q_OS_WIN
#  include <qt_windows.h>
#endif

QT_BEGIN_NAMESPACE

#if !(defined(QT_NO_SHAREDMEMORY) && defined(QT_NO_SYSTEMSEMAPHORE))
/*!
    \internal

    Generate a string from the key which can be any unicode string into
    the subset that the win/unix kernel allows.

    On Unix this will be a file name
  */
QString
QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
                                          const QString &prefix)
{
    if (key.isEmpty())
        return QString();

    QString result = prefix;

    for (QChar ch : key) {
        if ((ch >= QLatin1Char('a') && ch <= QLatin1Char('z')) ||
           (ch >= QLatin1Char('A') && ch <= QLatin1Char('Z')))
           result += ch;
    }

    QByteArray hex = QCryptographicHash::hash(key.toUtf8(), QCryptographicHash::Sha1).toHex();
    result.append(QLatin1String(hex));
#ifdef Q_OS_WIN
    return result;
#elif defined(QT_POSIX_IPC)
    return QLatin1Char('/') + result;
#else
    return QDir::tempPath() + QLatin1Char('/') + result;
#endif
}
#endif // QT_NO_SHAREDMEMORY && QT_NO_SHAREDMEMORY

#ifndef QT_NO_SHAREDMEMORY

/*!
  \class QSharedMemory
  \inmodule QtCore
  \since 4.4

  \brief The QSharedMemory class provides access to a shared memory segment.

  QSharedMemory provides access to a shared memory segment by multiple
  threads and processes. It also provides a way for a single thread or
  process to lock the memory for exclusive access.

  When using this class, be aware of the following platform
  differences:

  \list

  \li Windows: QSharedMemory does not "own" the shared memory segment.
  When all threads or processes that have an instance of QSharedMemory
  attached to a particular shared memory segment have either destroyed
  their instance of QSharedMemory or exited, the Windows kernel
  releases the shared memory segment automatically.

  \li Unix: QSharedMemory "owns" the shared memory segment. When the
  last thread or process that has an instance of QSharedMemory
  attached to a particular shared memory segment detaches from the
  segment by destroying its instance of QSharedMemory, the Unix kernel
  release the shared memory segment. But if that last thread or
  process crashes without running the QSharedMemory destructor, the
  shared memory segment survives the crash.

  \li HP-UX: Only one attach to a shared memory segment is allowed per
  process. This means that QSharedMemory should not be used across
  multiple threads in the same process in HP-UX.

  \endlist

  Remember to lock the shared memory with lock() before reading from
  or writing to the shared memory, and remember to release the lock
  with unlock() after you are done.

  QSharedMemory automatically destroys the shared memory segment when
  the last instance of QSharedMemory is detached from the segment, and
  no references to the segment remain.

  \warning QSharedMemory changes the key in a Qt-specific way, unless otherwise
  specified. Interoperation with non-Qt applications is achieved by first creating
  a default shared memory with QSharedMemory() and then setting a native key with
  setNativeKey(). When using native keys, shared memory is not protected against
  multiple accesses on it (for example, unable to lock()) and a user-defined mechanism
  should be used to achieve such protection.
 */

/*!
  \overload QSharedMemory()

  Constructs a shared memory object with the given \a parent.  The
  shared memory object's key is not set by the constructor, so the
  shared memory object does not have an underlying shared memory
  segment attached. The key must be set with setKey() or setNativeKey()
  before create() or attach() can be used.

  \sa setKey()
 */

#ifndef QT_NO_QOBJECT
QSharedMemory::QSharedMemory(QObject *parent)
  : QObject(*new QSharedMemoryPrivate, parent)
{
}
#else
QSharedMemory::QSharedMemory()
    : d_ptr(new QSharedMemoryPrivate)
{
}
#endif
/*!
  Constructs a shared memory object with the given \a parent and with
  its key set to \a key. Because its key is set, its create() and
  attach() functions can be called.

  \sa setKey(), create(), attach()
 */
#ifndef QT_NO_QOBJECT
QSharedMemory::QSharedMemory(const QString &key, QObject *parent)
    : QObject(*new QSharedMemoryPrivate, parent)
{
    setKey(key);
}
#else
QSharedMemory::QSharedMemory(const QString &key)
    : d_ptr(new QSharedMemoryPrivate)
{
    setKey(key);
}
#endif

/*!
  The destructor clears the key, which forces the shared memory object
  to \l {detach()} {detach} from its underlying shared memory
  segment. If this shared memory object is the last one connected to
  the shared memory segment, the detach() operation destroys the
  shared memory segment.

  \sa detach(), isAttached()
 */
QSharedMemory::~QSharedMemory()
{
    setKey(QString());
}

/*!
  Sets the platform independent \a key for this shared memory object. If \a key
  is the same as the current key, the function returns without doing anything.

  You can call key() to retrieve the platform independent key. Internally,
  QSharedMemory converts this key into a platform specific key. If you instead
  call nativeKey(), you will get the platform specific, converted key.

  If the shared memory object is attached to an underlying shared memory
  segment, it will \l {detach()} {detach} from it before setting the new key.
  This function does not do an attach().

  \sa key(), nativeKey(), isAttached()
*/
void QSharedMemory::setKey(const QString &key)
{
    Q_D(QSharedMemory);
    if (key == d->key && d->makePlatformSafeKey(key) == d->nativeKey)
        return;

    if (isAttached())
        detach();
    d->cleanHandle();
    d->key = key;
    d->nativeKey = d->makePlatformSafeKey(key);
}

/*!
  \since 4.8

  Sets the native, platform specific, \a key for this shared memory object. If
  \a key is the same as the current native key, the function returns without
  doing anything. If all you want is to assign a key to a segment, you should
  call setKey() instead.

  You can call nativeKey() to retrieve the native key. If a native key has been
  assigned, calling key() will return a null string.

  If the shared memory object is attached to an underlying shared memory
  segment, it will \l {detach()} {detach} from it before setting the new key.
  This function does not do an attach().

  The application will not be portable if you set a native key.

  \sa nativeKey(), key(), isAttached()
*/
void QSharedMemory::setNativeKey(const QString &key)
{
    Q_D(QSharedMemory);
    if (key == d->nativeKey && d->key.isNull())
        return;

    if (isAttached())
        detach();
    d->cleanHandle();
    d->key = QString();
    d->nativeKey = key;
}

bool QSharedMemoryPrivate::initKey()
{
    if (!cleanHandle())
        return false;
#ifndef QT_NO_SYSTEMSEMAPHORE
    systemSemaphore.setKey(QString(), 1);
    systemSemaphore.setKey(key, 1);
    if (systemSemaphore.error() != QSystemSemaphore::NoError) {
        QString function = QLatin1String("QSharedMemoryPrivate::initKey");
        errorString = QSharedMemory::tr("%1: unable to set key on lock").arg(function);
        switch(systemSemaphore.error()) {
        case QSystemSemaphore::PermissionDenied:
            error = QSharedMemory::PermissionDenied;
            break;
        case QSystemSemaphore::KeyError:
            error = QSharedMemory::KeyError;
            break;
        case QSystemSemaphore::AlreadyExists:
            error = QSharedMemory::AlreadyExists;
            break;
        case QSystemSemaphore::NotFound:
            error = QSharedMemory::NotFound;
            break;
        case QSystemSemaphore::OutOfResources:
            error = QSharedMemory::OutOfResources;
            break;
        case QSystemSemaphore::UnknownError:
        default:
            error = QSharedMemory::UnknownError;
            break;
        }
        return false;
    }
#endif
    errorString = QString();
    error = QSharedMemory::NoError;
    return true;
}

/*!
  Returns the key assigned with setKey() to this shared memory, or a null key
  if no key has been assigned, or if the segment is using a nativeKey(). The
  key is the identifier used by Qt applications to identify the shared memory
  segment.

  You can find the native, platform specific, key used by the operating system
  by calling nativeKey().

  \sa setKey(), setNativeKey()
 */
QString QSharedMemory::key() const
{
    Q_D(const QSharedMemory);
    return d->key;
}

/*!
  \since 4.8

  Returns the native, platform specific, key for this shared memory object. The
  native key is the identifier used by the operating system to identify the
  shared memory segment.

  You can use the native key to access shared memory segments that have not
  been created by Qt, or to grant shared memory access to non-Qt applications.

  \sa setKey(), setNativeKey()
*/
QString QSharedMemory::nativeKey() const
{
    Q_D(const QSharedMemory);
    return d->nativeKey;
}

/*!
  Creates a shared memory segment of \a size bytes with the key passed to the
  constructor, set with setKey() or set with setNativeKey(), then attaches to
  the new shared memory segment with the given access \a mode and returns
  \tt true. If a shared memory segment identified by the key already exists,
  the attach operation is not performed and \tt false is returned. When the
  return value is \tt false, call error() to determine which error occurred.

  \sa error()
 */
bool QSharedMemory::create(int size, AccessMode mode)
{
    Q_D(QSharedMemory);

    if (!d->initKey())
        return false;

#ifndef QT_NO_SYSTEMSEMAPHORE
#ifndef Q_OS_WIN
    // Take ownership and force set initialValue because the semaphore
    // might have already existed from a previous crash.
    d->systemSemaphore.setKey(d->key, 1, QSystemSemaphore::Create);
#endif
#endif

    QString function = QLatin1String("QSharedMemory::create");
#ifndef QT_NO_SYSTEMSEMAPHORE
    QSharedMemoryLocker lock(this);
    if (!d->key.isNull() && !d->tryLocker(&lock, function))
        return false;
#endif

    if (size <= 0) {
        d->error = QSharedMemory::InvalidSize;
        d->errorString =
            QSharedMemory::tr("%1: create size is less then 0").arg(function);
        return false;
    }

    if (!d->create(size))
        return false;

    return d->attach(mode);
}

/*!
  Returns the size of the attached shared memory segment. If no shared
  memory segment is attached, 0 is returned.

  \note The size of the segment may be larger than the requested size that was
  passed to create().

  \sa create(), attach()
 */
int QSharedMemory::size() const
{
    Q_D(const QSharedMemory);
    return d->size;
}

/*!
  \enum QSharedMemory::AccessMode

  \value ReadOnly The shared memory segment is read-only. Writing to
  the shared memory segment is not allowed. An attempt to write to a
  shared memory segment created with ReadOnly causes the program to
  abort.

  \value ReadWrite Reading and writing the shared memory segment are
  both allowed.
*/

/*!
  Attempts to attach the process to the shared memory segment
  identified by the key that was passed to the constructor or to a
  call to setKey() or setNativeKey(). The access \a mode is \l {QSharedMemory::}
  {ReadWrite} by default. It can also be \l {QSharedMemory::}
  {ReadOnly}. Returns \c true if the attach operation is successful. If
  false is returned, call error() to determine which error occurred.
  After attaching the shared memory segment, a pointer to the shared
  memory can be obtained by calling data().

  \sa isAttached(), detach(), create()
 */
bool QSharedMemory::attach(AccessMode mode)
{
    Q_D(QSharedMemory);

    if (isAttached() || !d->initKey())
        return false;
#ifndef QT_NO_SYSTEMSEMAPHORE
    QSharedMemoryLocker lock(this);
    if (!d->key.isNull() && !d->tryLocker(&lock, QLatin1String("QSharedMemory::attach")))
        return false;
#endif

    if (isAttached() || !d->handle())
        return false;

    return d->attach(mode);
}

/*!
  Returns \c true if this process is attached to the shared memory
  segment.

  \sa attach(), detach()
 */
bool QSharedMemory::isAttached() const
{
    Q_D(const QSharedMemory);
    return (0 != d->memory);
}

/*!
  Detaches the process from the shared memory segment. If this was the
  last process attached to the shared memory segment, then the shared
  memory segment is released by the system, i.e., the contents are
  destroyed. The function returns \c true if it detaches the shared
  memory segment. If it returns \c false, it usually means the segment
  either isn't attached, or it is locked by another process.

  \sa attach(), isAttached()
 */
bool QSharedMemory::detach()
{
    Q_D(QSharedMemory);
    if (!isAttached())
        return false;

#ifndef QT_NO_SYSTEMSEMAPHORE
    QSharedMemoryLocker lock(this);
    if (!d->key.isNull() && !d->tryLocker(&lock, QLatin1String("QSharedMemory::detach")))
        return false;
#endif

    return d->detach();
}

/*!
  Returns a pointer to the contents of the shared memory segment, if
  one is attached. Otherwise it returns null. Remember to lock the
  shared memory with lock() before reading from or writing to the
  shared memory, and remember to release the lock with unlock() after
  you are done.

  \sa attach()
 */
void *QSharedMemory::data()
{
    Q_D(QSharedMemory);
    return d->memory;
}

/*!
  Returns a const pointer to the contents of the shared memory
  segment, if one is attached. Otherwise it returns null. Remember to
  lock the shared memory with lock() before reading from or writing to
  the shared memory, and remember to release the lock with unlock()
  after you are done.

  \sa attach(), create()
 */
const void* QSharedMemory::constData() const
{
    Q_D(const QSharedMemory);
    return d->memory;
}

/*!
  \overload data()
 */
const void *QSharedMemory::data() const
{
    Q_D(const QSharedMemory);
    return d->memory;
}

#ifndef QT_NO_SYSTEMSEMAPHORE
/*!
  This is a semaphore that locks the shared memory segment for access
  by this process and returns \c true. If another process has locked the
  segment, this function blocks until the lock is released. Then it
  acquires the lock and returns \c true. If this function returns \c false,
  it means that you have ignored a false return from create() or attach(),
  that you have set the key with setNativeKey() or that
  QSystemSemaphore::acquire() failed due to an unknown system error.

  \sa unlock(), data(), QSystemSemaphore::acquire()
 */
bool QSharedMemory::lock()
{
    Q_D(QSharedMemory);
    if (d->lockedByMe) {
        qWarning("QSharedMemory::lock: already locked");
        return true;
    }
    if (d->systemSemaphore.acquire()) {
        d->lockedByMe = true;
        return true;
    }
    QString function = QLatin1String("QSharedMemory::lock");
    d->errorString = QSharedMemory::tr("%1: unable to lock").arg(function);
    d->error = QSharedMemory::LockError;
    return false;
}

/*!
  Releases the lock on the shared memory segment and returns \c true, if
  the lock is currently held by this process. If the segment is not
  locked, or if the lock is held by another process, nothing happens
  and false is returned.

  \sa lock()
 */
bool QSharedMemory::unlock()
{
    Q_D(QSharedMemory);
    if (!d->lockedByMe)
        return false;
    d->lockedByMe = false;
    if (d->systemSemaphore.release())
        return true;
    QString function = QLatin1String("QSharedMemory::unlock");
    d->errorString = QSharedMemory::tr("%1: unable to unlock").arg(function);
    d->error = QSharedMemory::LockError;
    return false;
}
#endif // QT_NO_SYSTEMSEMAPHORE

/*!
  \enum QSharedMemory::SharedMemoryError

  \value NoError No error occurred.

  \value PermissionDenied The operation failed because the caller
  didn't have the required permissions.

  \value InvalidSize A create operation failed because the requested
  size was invalid.

  \value KeyError The operation failed because of an invalid key.

  \value AlreadyExists A create() operation failed because a shared
  memory segment with the specified key already existed.

  \value NotFound An attach() failed because a shared memory segment
  with the specified key could not be found.

  \value LockError The attempt to lock() the shared memory segment
  failed because create() or attach() failed and returned false, or
  because a system error occurred in QSystemSemaphore::acquire().

  \value OutOfResources A create() operation failed because there was
  not enough memory available to fill the request.

  \value UnknownError Something else happened and it was bad.
*/

/*!
  Returns a value indicating whether an error occurred, and, if so,
  which error it was.

  \sa errorString()
 */
QSharedMemory::SharedMemoryError QSharedMemory::error() const
{
    Q_D(const QSharedMemory);
    return d->error;
}

/*!
  Returns a text description of the last error that occurred. If
  error() returns an \l {QSharedMemory::SharedMemoryError} {error
  value}, call this function to get a text string that describes the
  error.

  \sa error()
 */
QString QSharedMemory::errorString() const
{
    Q_D(const QSharedMemory);
    return d->errorString;
}

#endif // QT_NO_SHAREDMEMORY

QT_END_NAMESPACE

#ifndef QT_NO_QOBJECT
#include "moc_qsharedmemory.cpp"
#endif
