/* * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License */ /* * @file file-lock.cpp * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com) * @version 1.0 */ #include "file-lock.h" #include #include #include #include #include #include #include #include #include #include namespace CKM { namespace { // TODO replace it with custom exception when they are implemented template std::runtime_error io_exception(const Args &... args) { return std::runtime_error(Stringify::Merge(args...)); }; } // namespace anonymous FileLock::FileLock(const char *const file) { // Open lock file m_lockFd = TEMP_FAILURE_RETRY(creat(file, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)); if (m_lockFd == -1) throw io_exception("Cannot open lock file. Errno: ", GetErrnoString()); if (-1 == lockf(m_lockFd, F_TLOCK, 0)) { if (errno == EACCES || errno == EAGAIN) throw io_exception("Can't acquire lock. Another instance must be running."); else throw io_exception("Can't acquire lock. Errno: ", GetErrnoString()); } std::string pid = std::to_string(getpid()); ssize_t written = TEMP_FAILURE_RETRY(write(m_lockFd, pid.c_str(), pid.size())); if (-1 == written || static_cast(pid.size()) > written) throw io_exception("Can't write file lock. Errno: ", GetErrnoString()); int ret = fsync(m_lockFd); if (-1 == ret) throw io_exception("Fsync failed. Errno: ", GetErrnoString()); } FileLock::~FileLock() { // this will also release the lock close(m_lockFd); } } /* namespace CKM */