Added FileLocker class
[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     try {
45         m_locked = false;
46         m_blocking = blocking;
47         m_lockFile = lockFile;
48         Lock();
49     } catch (FileLocker::Exception::Base &e) {
50         LogError("Failed to lock " << lockFile << " file: "
51                  << e.DumpToString());
52         ThrowMsg(FileLocker::Exception::LockFailed,
53                  "Failed to lock " << lockFile << " file: "
54                  << e.DumpToString());
55     }
56 }
57
58 FileLocker::~FileLocker()
59 {
60     Unlock();
61 }
62
63 bool FileLocker::Locked()
64 {
65     return m_locked;
66 }
67
68 void FileLocker::Lock()
69 {
70     if (m_locked)
71         return;
72     try {
73         if (!std::ifstream(m_lockFile).good())
74             std::ofstream(m_lockFile.c_str());
75         m_flock = boost::interprocess::file_lock(m_lockFile.c_str());
76         if (m_blocking) {
77             m_flock.lock();
78             m_locked = true;
79         } else
80             m_locked = m_flock.try_lock();
81     } catch (const std::exception &e) {
82             ThrowMsg(FileLocker::Exception::LockFailed,
83                      "Error while locking a file.");
84     }
85     if (m_locked) {
86         LogDebug("We have a lock on " << m_lockFile << " file.");
87     } else {
88         if (m_blocking) {
89             ThrowMsg(FileLocker::Exception::LockFailed,
90                      "Unable to lock file.");
91         } else {
92             LogDebug("Impossible to lock a file now.");
93         }
94     }
95 }
96
97 void FileLocker::Unlock()
98 {
99     if (m_locked) {
100         m_flock.unlock();
101         LogDebug("Lock released.");
102     }
103 }
104
105 } // namespace SecurityManager
106