Fix advisory locking in client library
[platform/core/security/security-manager.git] / src / common / file-lock.cpp
1 /*
2  *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Rafal Krypa <r.krypa@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18 /*
19  * @file        file-lock.cpp
20  * @author      Sebastian Grabowski (s.grabowski@samsung.com)
21  * @version     1.0
22  * @brief       Implementation of simple file locking for a service
23  */
24 /* vim: set ts=4 et sw=4 tw=78 : */
25
26 #include <fstream>
27 #include <dpl/log/log.h>
28
29 #include "file-lock.h"
30
31 namespace SecurityManager {
32
33 char const * const SERVICE_LOCK_FILE = tzplatform_mkpath3(TZ_SYS_RUN,
34                                                          "lock",
35                                                          "security-manager.lock");
36
37 FileLocker::FileLocker(const std::string &lockFile, bool blocking)
38 {
39     if (lockFile.empty()) {
40         LogError("File name can not be empty.");
41         ThrowMsg(FileLocker::Exception::LockFailed,
42                  "File name can not be empty.");
43     }
44
45     m_locked = false;
46     m_blocking = blocking;
47     m_lockFile = lockFile;
48     Lock();
49 }
50
51 FileLocker::~FileLocker()
52 {
53     Unlock();
54 }
55
56 bool FileLocker::Locked()
57 {
58     return m_locked;
59 }
60
61 void FileLocker::Lock()
62 {
63     if (m_locked)
64         return;
65
66     try {
67         std::ofstream tmpf(m_lockFile);
68         tmpf.close();
69
70         m_flock = boost::interprocess::file_lock(m_lockFile.c_str());
71         if (m_blocking) {
72             m_flock.lock();
73             m_locked = true;
74         } else
75             m_locked = m_flock.try_lock();
76     } catch (const std::exception &e) {
77         LogError("Error while locking a file: " << e.what());
78         ThrowMsg(FileLocker::Exception::LockFailed,
79                  "Error while locking a file: " << e.what());
80     }
81
82     if (m_locked)
83         LogDebug("We have a lock on " << m_lockFile << " file.");
84     else
85         LogDebug("Impossible to lock a file now.");
86 }
87
88 void FileLocker::Unlock()
89 {
90     if (m_locked) {
91         m_flock.unlock();
92         m_locked = false;
93         LogDebug("Lock released.");
94     }
95 }
96
97 } // namespace SecurityManager
98