/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/

#include "android/utils/filelock.h"

#include "android/base/system/System.h"
#include "android/utils/eintr_wrapper.h"
#include "android/utils/lock.h"
#include "android/utils/path.h"

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>
#ifdef _WIN32
#  include "android/base/memory/ScopedPtr.h"
#  include "android/base/system/Win32UnicodeString.h"
#  ifndef WIN32_LEAN_AND_MEAN
#    define WIN32_LEAN_AND_MEAN
#  endif
#  include <windows.h>
#else
#  include <sys/types.h>
#  include <unistd.h>
#  include <signal.h>
#endif

using android::base::System;

// Set to 1 to enable debug traces here.
#if 0
#define  D(...)  printf(__VA_ARGS__), printf("\n"), fflush(stdout)
#else
#define D(...) ((void)0)
#endif

/** FILE LOCKS SUPPORT
 **
 ** A FileLock is useful to prevent several emulator instances from using
 ** the same writable file (e.g. the userdata.img disk images).
 **
 ** Create a FileLock object with filelock_create(), this function should
 ** return NULL only if the corresponding file path could not be locked.
 **
 ** All file locks are automatically released and destroyed when the program
 ** exits. The filelock_lock() function can also detect stale file locks
 ** that can linger when the emulator crashes unexpectedly, and will happily
 ** clean them for you
 **
 ** Here's how it works, three files are used:
 **     file  - the data file accessed by the emulator
 **     lock  - a lock file  (file + '.lock')
 **     temp  - a temporary file made unique with mkstemp
 **
 ** When locking:
 **      create 'temp' and store our pid in it
 **      attemp to link 'lock' to 'temp'
 **         if the link succeeds, we obtain the lock
 **      unlink 'temp'
 **
 ** When unlocking:
 **      unlink 'lock'
 **
 **/


/* Thread safety:
 *     _all_filelocks_tl: Hold this when accessing |_all_filelocks|.
 *                        This is locked at exit, so hold this for very, *very*
 *                        short.
 */
static CLock* _all_filelocks_tl;
/* This is set to true during exit.
 * All accesses of _all_filelocks should strictly follow this scheme:
 *   android_lock_acquire(_all_filelocks_tl);
 *   if (!_is_exiting) {
 *     // Safe to access _all_filelocks now.
 *   }
 *   android_lock_release(_all_filelocks_tl);
 */
static bool _is_exiting = false;

struct FileLock
{
  const char*  file;
  const char*  lock;
  char*        temp;
#ifdef _WIN32
  HANDLE       lock_handle;
#endif
  int          locked;
  FileLock*    next;
};

/* used to cleanup all locks at emulator exit */
static FileLock*   _all_filelocks;

#define  LOCK_NAME   ".lock"
#define  TEMP_NAME   ".tmp-XXXXXX"
#define  WIN_PIDFILE_NAME  "pid"

void
filelock_init() {
    _all_filelocks_tl = android_lock_new();
}

#ifdef _WIN32
template <class Func>
static bool retry(Func func, int tries = 4, int timeoutMs = 100) {
    for (;;) {
        if (func()) {
            return true;
        }
        if (--tries == 0) {
            return false;
        }
        System::get()->sleepMs(timeoutMs);
    }
}

static bool delete_file(const android::base::Win32UnicodeString& name) {
    return retry([&name]() {
        return ::DeleteFileW(name.c_str()) != 0 ||
               ::GetLastError() == ERROR_FILE_NOT_FOUND;
    });
}

static bool delete_dir(const android::base::Win32UnicodeString& name) {
    return retry([&name]() {
        return ::RemoveDirectoryW(name.c_str()) != 0 ||
               ::GetLastError() == ERROR_FILE_NOT_FOUND;
    });
}

/* returns 0 on success, -1 on failure */
static int filelock_lock(FileLock* lock) {
    lock->lock_handle = nullptr;
    const auto unicodeDir = android::base::Win32UnicodeString(lock->lock);
    const auto unicodeName = android::base::Win32UnicodeString(lock->temp);

    HANDLE lockHandle = INVALID_HANDLE_VALUE;
    const bool createFileResult = retry(
        [&lockHandle, &unicodeDir, &unicodeName]() {
            if (!::CreateDirectoryW(unicodeDir.c_str(), nullptr) &&
                ::GetLastError() != ERROR_ALREADY_EXISTS) {
                return false;
            }

            // Open/create a lock file with a flags combination like:
            //  - open for writing only
            //  - allow only one process to open file for writing (our process)
            // Together, this guarantees that the file can only be opened when
            // our process is alive and keeps a handle to it.
            // As soon as our process ends or we close/delete it - other lock
            // can be acquired.
            // Note: FILE_FLAG_DELETE_ON_CLOSE doesn't work well here, as
            //  everyone else would need to open the file in FILE_SHARE_DELETE
            //  mode, and both Android Studio and cmd.exe don't use it. Fix
            //  at least the Android Studio part before trying to add this flag
            //  instead of the manual deletion code.
            lockHandle = ::CreateFileW(
                    unicodeName.c_str(),
                    GENERIC_WRITE,    // open only for writing
                    FILE_SHARE_READ,  // allow others to read the file, but not
                                      // to write to it or not to delete it
                    nullptr,          // no special security attributes
                    CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY,
                    nullptr);  // no template file
            return lockHandle != INVALID_HANDLE_VALUE;
        },
        5,      // tries
        200);   // sleep timeout between tries

    if (!createFileResult) {
        assert(lockHandle == INVALID_HANDLE_VALUE);
        return -1;
    }

    assert(lockHandle != INVALID_HANDLE_VALUE);

    // Make sure we kill the file/directory on any failure.
    auto fileDeleter = android::base::makeCustomScopedPtr(
            lockHandle, [&unicodeName, &unicodeDir](HANDLE h) {
                ::CloseHandle(h);
                delete_file(unicodeName);
                delete_dir(unicodeDir);
            });

    // We're good. Now write down the process ID as Android Studio relies on it.
    const DWORD pid = ::GetCurrentProcessId();
    char pidBuf[12];
    const int len = snprintf(pidBuf, sizeof(pidBuf), "%lu", pid);
    assert(len > 0 && len < (int)sizeof(pidBuf));
    DWORD bytesWritten;
    if (!::WriteFile(lockHandle, pidBuf, static_cast<DWORD>(len), &bytesWritten,
                     nullptr) ||
        bytesWritten != static_cast<DWORD>(len)) {
        D("Failed to write the current PID into the lock file");
        return -1;
    }
    lock->locked = 1;
    lock->lock_handle = fileDeleter.release();
    return 0;  // we're all good
}
#else
/* returns 0 on success, -1 on failure */
static int filelock_lock(FileLock* lock) {
    int    ret;
    int    temp_fd = -1;
    int    lock_fd = -1;
    int    rc, tries;
    FILE*  f = NULL;
    char   pid[8];
    struct stat  st_temp;
    int sleep_duration_ms = 0;

    temp_fd = mkstemp(lock->temp);

    if (temp_fd < 0) {
        D("Cannot create locking temp file '%s'", lock->temp);
        goto Fail;
    }

    snprintf(pid, sizeof pid, "%d", getpid());
    ret = HANDLE_EINTR(write(temp_fd, pid, strlen(pid) + 1));
    if (ret < 0) {
        D("Cannot write to locking temp file '%s'", lock->temp);
        goto Fail;
    }
    close(temp_fd);
    temp_fd = -1;

    rc = HANDLE_EINTR(lstat(lock->temp, &st_temp));
    if (rc < 0) {
        D("Can't properly stat our locking temp file '%s'", lock->temp);
        goto Fail;
    }

    /* now attempt to link the temp file to the lock file */
    for (tries = 4; tries > 0; tries--)
    {
        const int kSleepDurationMsMax = 2000;  // 2 seconds.
        const int kSleepDurationMsIncrement = 50;

        if (sleep_duration_ms > 0) {
            if (sleep_duration_ms > kSleepDurationMsMax) {
                D("Cannot acquire lock file '%s'", lock->lock);
                goto Fail;
            }
            System::get()->sleepMs(sleep_duration_ms);
        }
        sleep_duration_ms += kSleepDurationMsIncrement;

        // The return value of link() is buggy on NFS, so ignore it.
        // and use lstat() to look at the result.
        rc = HANDLE_EINTR(link(lock->temp, lock->lock));

        struct stat st_lock;
        rc = HANDLE_EINTR(lstat(lock->lock, &st_lock));
        if (rc != 0) {
            // Try again after sleeping a little.
            continue;
        }

        if (st_temp.st_rdev == st_lock.st_rdev &&
            st_temp.st_ino  == st_lock.st_ino  ) {
            /* The link() operation suceeded */
            lock->locked = 1;
            rc = HANDLE_EINTR(unlink(lock->temp));
            return 0;
        }

        if (S_ISDIR(st_lock.st_mode)) {
            char *win_pid;
            int win_pid_len;
            // The .lock file is a directory. This can only happen
            // when the AVD was previously used by a Win32 emulator
            // instance running under Wine on the same machine.
            fprintf(stderr,
                    "Stale Win32 lock file detected: %s\n",
                    lock->lock);

            /* Try deleting the pid file dropped in windows.
             * Ignore error -- try blowing away the directory anyway.
             */
            win_pid_len = strlen(lock->lock) + 1 + sizeof(WIN_PIDFILE_NAME);
            win_pid = (char *) malloc(win_pid_len);
            snprintf(win_pid, win_pid_len, "%s/" WIN_PIDFILE_NAME, lock->lock);
            HANDLE_EINTR(unlink(win_pid));
            free(win_pid);

            rc = HANDLE_EINTR(rmdir(lock->lock));
            if (rc != 0) {
                D("Removing stale Win32 lockfile '%s' failed (%s)",
                  lock->lock, strerror(errno));
            }

            goto Fail;
        }

        /* if we get there, it means that the link() call failed */
        /* check the lockfile to see if it is stale              */
        typedef enum {
            FRESHNESS_UNKNOWN = 0,
            FRESHNESS_FRESH,
            FRESHNESS_STALE,
        } Freshness;

        Freshness freshness = FRESHNESS_UNKNOWN;

        struct stat st;
        time_t now;
        rc = HANDLE_EINTR(time(&now));
        st.st_mtime = now - 120;

        int lockpid = 0;
        int lockfd = HANDLE_EINTR(open(lock->lock,O_RDONLY));
        if (lockfd >= 0) {
            char buf[16];
            int len = HANDLE_EINTR(read(lockfd, buf, sizeof(buf) - 1U));
            if (len < 0) {
                len = 0;
            }
            buf[len] = 0;
            lockpid = atoi(buf);

            rc = HANDLE_EINTR(fstat(lockfd, &st));
            if (rc == 0) {
                now = st.st_atime;
            }
            IGNORE_EINTR(close(lockfd));
        }
        /* if there is a PID, check that it is still alive */
        if (lockpid > 0) {
            rc = HANDLE_EINTR(kill(lockpid, 0));
            if (rc == 0 || errno == EPERM) {
                freshness = FRESHNESS_FRESH;
            } else if (rc < 0 && errno == ESRCH) {
                freshness = FRESHNESS_STALE;
            }
        }
        if (freshness == FRESHNESS_UNKNOWN) {
            /* no pid, stale if the file is older than 1 minute */
            freshness = (now >= st.st_mtime + 60) ?
                    FRESHNESS_STALE :
                    FRESHNESS_FRESH;
        }

        if (freshness == FRESHNESS_STALE) {
            D("Removing stale lockfile '%s'", lock->lock);
            rc = HANDLE_EINTR(unlink(lock->lock));
            sleep_duration_ms = 0;
            tries++;
        }
    }
    D("file '%s' is already in use by another process", lock->file);

Fail:
    if (f) {
        fclose(f);
    }

    if (temp_fd >= 0) {
        IGNORE_EINTR(close(temp_fd));
    }

    if (lock_fd >= 0) {
        IGNORE_EINTR(close(lock_fd));
    }

    HANDLE_EINTR(unlink(lock->temp));
    return -1;
}
#endif

void
filelock_release( FileLock*  lock )
{
    if (lock->locked) {
#ifdef _WIN32
        ::CloseHandle(lock->lock_handle);
        lock->lock_handle = nullptr;
        delete_file(android::base::Win32UnicodeString(lock->temp));
        delete_dir(android::base::Win32UnicodeString(lock->lock));
#else
        unlink( (char*)lock->lock );
#endif
        lock->locked = 0;
    }
}

static void
filelock_atexit( void )
{
  FileLock*  lock;

  android_lock_acquire(_all_filelocks_tl);
  if (!_is_exiting) {
    for (lock = _all_filelocks; lock != NULL; lock = lock->next) {
        filelock_release( lock );
    }
  }
  _is_exiting = true;
  android_lock_release(_all_filelocks_tl);
  // We leak |_all_filelocks_tl| here. We can never guarantee that another
  // thread isn't trying to use filelock concurrently, so we can not safely
  // clean up the mutex. See b.android.com/209635
}

/* create a file lock */
FileLock*
filelock_create( const char*  file )
{
    int    file_len = strlen(file);
    int    lock_len = file_len + sizeof(LOCK_NAME);
#ifdef _WIN32
    int    temp_len = lock_len + 1 + sizeof(WIN_PIDFILE_NAME);
#else
    int    temp_len = file_len + sizeof(TEMP_NAME);
#endif
    int    total_len = sizeof(FileLock) + file_len + lock_len + temp_len + 3;

    FileLock* lock = (FileLock*)malloc(total_len);

    lock->file = (const char*)(lock + 1);
    memcpy( (char*)lock->file, file, file_len+1 );

    lock->lock = lock->file + file_len + 1;
    memcpy( (char*)lock->lock, file, file_len+1 );
    strcat( (char*)lock->lock, LOCK_NAME );

    lock->temp    = (char*)lock->lock + lock_len + 1;
#ifdef _WIN32
    snprintf( (char*)lock->temp, temp_len, "%s\\" WIN_PIDFILE_NAME,
              lock->lock );
#else
    snprintf((char*)lock->temp, temp_len, "%s%s", lock->file, TEMP_NAME);
#endif
    lock->locked = 0;

    if (filelock_lock(lock) < 0) {
        free(lock);
        return NULL;
    }

    android_lock_acquire(_all_filelocks_tl);
    if (_is_exiting) {
        android_lock_release(_all_filelocks_tl);
        return NULL;
    }

    lock->next     = _all_filelocks;
    _all_filelocks = lock;
    android_lock_release(_all_filelocks_tl);

    if (lock->next == NULL)
        atexit( filelock_atexit );

    return lock;
}
