};
if (::socketpair(AF_LOCAL, flags, 0, mSockets.data()) < 0) {
- const std::string msg = "socketpair() failed: " +
- utils::getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in socketpair()", errno);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Maciej Karpiuk (m.karpiuk2@samsung.com)
+ *
+ * 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
+ * @author Maciej Karpiuk (m.karpiuk2@samsung.com)
+ * @brief Credential management related functions
+ */
+
+#include "utils/credentials.hpp"
+#include "utils/exception.hpp"
+#include "logger/logger.hpp"
+
+#include <unistd.h>
+#include <grp.h>
+#include <vector>
+
+namespace utils {
+
+// ------------------- syscall wrappers -------------------
+void setgroups(const std::vector<gid_t>& gids)
+{
+ if (::setgroups(gids.size(), gids.data()) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in setgroups()", errno);
+ }
+}
+
+void setregid(const gid_t rgid, const gid_t egid)
+{
+ if (::setregid(rgid, egid) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in setregid()", errno);
+ }
+}
+
+void setreuid(const uid_t ruid, const uid_t euid)
+{
+ if (::setreuid(ruid, euid) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in setreuid()", errno);
+ }
+}
+
+pid_t setsid()
+{
+ pid_t pid = ::setsid();
+ if (pid == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in setsid()", errno);
+ }
+ return pid;
+}
+
+} // namespace utils
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Maciej Karpiuk (m.karpiuk2@samsung.com)
+ *
+ * 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
+ * @author Maciej Karpiuk (m.karpiuk2@samsung.com)
+ * @brief Credential management related functions
+ */
+
+#include <sys/types.h>
+#include <vector>
+
+namespace utils {
+
+// ------------------- syscall wrappers -------------------
+// Throw exception on error
+void setgroups(const std::vector<gid_t>& groups);
+void setregid(const gid_t rgid, const gid_t egid);
+void setreuid(const uid_t ruid, const uid_t euid);
+pid_t setsid();
+
+
+} // namespace utils
#ifndef COMMON_UTILS_EXCEPTION_HPP
#define COMMON_UTILS_EXCEPTION_HPP
+#include "logger/logger.hpp"
#include <stdexcept>
namespace utils {
+/**
+ * Return string describing error number
+ * it is wrapper for strerror_r
+ */
+std::string getSystemErrorMessage();
+std::string getSystemErrorMessage(int err);
/**
* Base class for exceptions in utils
*/
-struct UtilsException: public std::runtime_error {
+struct UtilsException : public std::runtime_error {
+ explicit UtilsException(const std::string& error,
+ int errno_,
+ const char *file,
+ const char *func,
+ int line,
+ logger::LogLevel level = logger::LogLevel::DEBUG)
+ : std::runtime_error(error),
+ mErrno(errno_),
+ mFile(std::string(file?file:__FILE__)),
+ mFunc(std::string(func?func:__func__)),
+ mLine((line!=-1)?__LINE__:line),
+ mLevel(level) {
+ if (logger::Logger::getLogLevel() <= mLevel) {
+ logger::Logger::logMessage(mLevel,
+ (mErrno!=0)?(error + " (errno: " + getSystemErrorMessage(mErrno) + ")"):error,
+ mFile,
+ mLine,
+ mFunc,
+ PROJECT_SOURCE_DIR);
+ }
+ }
- explicit UtilsException(const std::string& error) : std::runtime_error(error) {}
-};
+ explicit UtilsException(const std::string& error, int errno_)
+ : UtilsException(error, errno_, nullptr, nullptr, -1) {}
-struct EventFDException: public UtilsException {
+ explicit UtilsException(const std::string& error)
+ : UtilsException(error, errno) {}
- explicit EventFDException(const std::string& error) : UtilsException(error) {}
+ const int mErrno;
+ const std::string mFile;
+ const std::string mFunc;
+ const int mLine;
+ logger::LogLevel mLevel;
};
-struct ProvisionExistsException: public UtilsException {
+#define THROW_UTILS_EXCEPTION__(LEVEL, MSG, ERRNO, FILE, LINE, FUNC)\
+ do { \
+ int errnoTmp = ERRNO; \
+ std::ostringstream messageStream__; \
+ messageStream__ << MSG; \
+ throw UtilsException(messageStream__.str(), \
+ errnoTmp, \
+ FILE, \
+ FUNC, \
+ LINE, \
+ logger::LogLevel::LEVEL); \
+ } while (0)
+
+#define THROW_UTILS_EXCEPTION_W(MSG) \
+ THROW_UTILS_EXCEPTION__(WARN, MSG, 0, __FILE__, __LINE__, __func__)
+
+#define THROW_UTILS_EXCEPTION_ERRNO_W(MSG, ERRNO) \
+ THROW_UTILS_EXCEPTION__(WARN, MSG, ERRNO, __FILE__, __LINE__, __func__)
+
+#define THROW_UTILS_EXCEPTION_D(MSG) \
+ THROW_UTILS_EXCEPTION__(DEBUG, MSG, 0, __FILE__, __LINE__, __func__)
- explicit ProvisionExistsException(const std::string& error) : UtilsException(error) {}
+#define THROW_UTILS_EXCEPTION_ERRNO_D(MSG, ERRNO) \
+ THROW_UTILS_EXCEPTION__(DEBUG, MSG, ERRNO, __FILE__, __LINE__, __func__)
+
+#define THROW_UTILS_EXCEPTION_E(MSG) \
+ THROW_UTILS_EXCEPTION__(ERROR, MSG, 0, __FILE__, __LINE__, __func__)
+
+#define THROW_UTILS_EXCEPTION_ERRNO_E(MSG, ERRNO) \
+ THROW_UTILS_EXCEPTION__(ERROR, MSG, ERRNO, __FILE__, __LINE__, __func__)
+
+struct EventFDException: public UtilsException {
+
+ explicit EventFDException(const std::string& error) : UtilsException(error) {}
};
-/**
- * Return string describing error number
- * it is wrapper for strerror_r
- */
-std::string getSystemErrorMessage();
-std::string getSystemErrorMessage(int err);
} // namespace utils
for (;;) {
chr::milliseconds timeoutMS = chr::duration_cast<chr::milliseconds>(deadline - chr::high_resolution_clock::now());
if (timeoutMS.count() < 0) {
- LOGE("Timeout while waiting for event: " << std::hex << event <<
+ THROW_UTILS_EXCEPTION_E("Timeout while waiting for event: " << std::hex << event <<
" on fd: " << std::dec << fd);
- throw UtilsException("Timeout");
}
int ret = ::poll(fds, 1 /*fds size*/, timeoutMS.count());
if (errno == EINTR) {
continue;
}
- const std::string msg = "Error in poll: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in poll", errno);
}
if (ret == 0) {
- const std::string msg = "Timeout in read";
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_E("Timeout in read");
}
if (fds[0].revents & event) {
}
if (fds[0].revents & POLLHUP) {
- const std::string msg = "Peer disconnected";
- LOGW(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_W("Peer disconnected");
}
}
}
{
int ret = ::fcntl(fd, getOp);
if (ret == -1) {
- std::string msg = "fcntl(): Failed to get FD flags: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("fcntl(): Failed to get FD flags", errno);
}
if (set) {
}
if (ret == -1) {
- std::string msg = "fcntl(): Failed to set FD flag: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("fcntl(): Failed to set FD flag", errno);
}
}
assert(!((flags & O_CREAT) == O_CREAT || (flags & O_TMPFILE) == O_TMPFILE) || mode != static_cast<unsigned>(-1));
int fd;
-
for (;;) {
fd = ::open(path.c_str(), flags, mode);
LOGT("open() interrupted by a signal, retrying");
continue;
}
- const std::string msg = "open() failed: " + path + ": " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E(path + ": open() failed", errno);
}
break;
}
return fd;
}
-void close(int fd)
+void close(int fd) noexcept
{
if (fd < 0) {
return;
}
if (-1 == ::shutdown(fd, SHUT_RDWR)) {
- std::string msg = "shutdown() failed: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("shutdown() failed", errno);
}
}
{
int ret = ::ioctl(fd, request, argp);
if (ret == -1) {
- const std::string msg = "ioctl() failed: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("ioctl() failed", errno);
}
return ret;
}
}
int fd = dup3(oldFD, newFD, flags);
if (fd == -1) {
- const std::string msg = "dup3() failed: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("dup3() failed", errno);
}
return fd;
}
// Neglected errors
LOGD("Retrying write");
} else {
- const std::string msg = "Error during writing: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error during write()", errno);
}
waitForEvent(fd, POLLOUT, deadline);
break;
}
if (n == 0) {
- const std::string msg = "Peer disconnected";
- LOGW(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_W("Peer disconnected");
}
} else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
// Neglected errors
LOGD("Retrying read");
} else {
- const std::string msg = "Error during reading: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error during read()", errno);
}
waitForEvent(fd, POLLIN, deadline);
unsigned int getMaxFDNumber()
{
struct rlimit rlim;
- if (-1 == getrlimit(RLIMIT_NOFILE, &rlim)) {
- const std::string msg = "Error during getrlimit: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ if (-1 == ::getrlimit(RLIMIT_NOFILE, &rlim)) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error during getrlimit()", errno);
}
return rlim.rlim_cur;
}
struct rlimit rlim;
rlim.rlim_cur = limit;
rlim.rlim_max = limit;
- if (-1 == setrlimit(RLIMIT_NOFILE, &rlim)) {
- const std::string msg = "Error during setrlimit: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ if (-1 == ::setrlimit(RLIMIT_NOFILE, &rlim)) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error during setrlimit()", errno);
}
}
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
// Neglected errors, retry
} else {
- throw UtilsException("Error during recvmsg: " + getSystemErrorMessage());
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error during recvmsg()", errno);
}
} else if (ret == 0) {
- throw UtilsException("Peer disconnected");
+ THROW_UTILS_EXCEPTION_W("Peer disconnected");
} else {
// We receive only 1 byte of data. No need to repeat
break;
struct cmsghdr *cmhp;
cmhp = CMSG_FIRSTHDR(&msgh);
if (cmhp == NULL || cmhp->cmsg_len != CMSG_LEN(sizeof(int))) {
- throw UtilsException("Bad cmsg length");
+ THROW_UTILS_EXCEPTION_D("Bad cmsg length");
} else if (cmhp->cmsg_level != SOL_SOCKET) {
- throw UtilsException("cmsg_level != SOL_SOCKET");
+ THROW_UTILS_EXCEPTION_D("cmsg_level != SOL_SOCKET");
} else if (cmhp->cmsg_type != SCM_RIGHTS) {
- throw UtilsException("cmsg_type != SCM_RIGHTS");
+ THROW_UTILS_EXCEPTION_D("cmsg_type != SCM_RIGHTS");
}
return *(reinterpret_cast<int*>(CMSG_DATA(cmhp)));
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
// Neglected errors, retry
} else {
- throw UtilsException("Error during sendmsg: " + getSystemErrorMessage());
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error during sendmsg()", errno);
}
} else if (ret == 0) {
// Retry the sending
}
} // namespace utils
-
namespace utils {
+// TODO: add check for errno==EINTR where applicable
+// (as few syscall wrappers already have it)
+
/**
* Open a file.
*/
/**
* Close the file descriptor.
*/
-void close(int fd);
+void close(int fd) noexcept;
/**
* Shut down part of a full-duplex connection
poll.dispatchIteration(std::chrono::duration_cast<std::chrono::milliseconds>(duration).count());
}
- if(isWaiting) {
- throw UtilsException("No such file: " + file);
+ if (isWaiting) {
+ THROW_UTILS_EXCEPTION_D("No such file: " << file);
}
}
#include "config.hpp"
#include "logger/logger.hpp"
+#include "utils/fd-utils.hpp"
#include "utils/fs.hpp"
#include "utils/paths.hpp"
+#include "utils/smack.hpp"
+#include "utils/text.hpp"
#include "utils/exception.hpp"
#include <boost/filesystem.hpp>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
+#include <sys/syscall.h>
#include <iostream>
-
namespace fs = boost::filesystem;
namespace utils {
-std::string readFileStream(const std::string& path)
+
+// ------------------- syscalls -------------------
+bool remove(const std::string& path)
{
- std::ifstream file(path);
+ if (::remove(path.c_str()) == -1) {
+ if (errno == ENOENT) {
+ LOGW(path << ": not removed, path does not exist");
+ return false;
+ }
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": failed to remove", errno);
+ }
- if (!file) {
- throw UtilsException("Read failed");
+ return true;
+}
+
+struct ::stat stat(const std::string & path)
+{
+ struct ::stat s;
+ if (::stat(path.c_str(), &s) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": failed to get stat", errno);
}
- // 2 x faster then std::istreambuf_iterator
- std::stringstream content;
- content << file.rdbuf();
- return content.str();
+ return s;
}
-bool readFileStream(const std::string& path, std::string& result)
+struct ::statfs statfs(const std::string & path)
{
- std::ifstream file(path);
+ int rc;
+ struct ::statfs s;
+ do {
+ rc = ::statfs(path.c_str(), &s);
+ } while (rc == -1 && errno == EINTR);
- if (!file) {
- return false;
+ if (rc == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": failed to get statfs", errno);
+ }
+ return s;
+}
+
+bool access(const std::string& path, int mode)
+{
+ if (::access(path.c_str(), mode) == -1) {
+ if (errno == EACCES) {
+ return false;
+ }
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": trying to access() failed", errno);
}
- std::stringstream content;
- content << file.rdbuf();
- result = content.str();
return true;
}
-std::string readFileContent(const std::string& path)
+void mount(const std::string& source,
+ const std::string& target,
+ const std::string& filesystemtype,
+ unsigned long mountflags,
+ const std::string& data)
{
- std::string result;
+ int ret = ::mount(source.c_str(),
+ target.c_str(),
+ filesystemtype.c_str(),
+ mountflags,
+ data.c_str());
+ if (ret == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Mount operation failure: source path: "
+ << source
+ << ", target path: "
+ << target
+ << ", filesystemtype: "
+ << filesystemtype
+ << ", mountflags: "
+ << std::to_string(mountflags)
+ << ", data: "
+ << data, errno);
+ }
+}
- if (!readFileContent(path, result)) {
- throw UtilsException("Read failed");
+void umount(const std::string& path, int flags)
+{
+ if (::umount2(path.c_str(), flags) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": umount failed", errno);
+ }
+}
+
+void mkfifo(const std::string& path, mode_t mode)
+{
+ if (::mkfifo(path.c_str(), mode) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": failed to create fifo", errno);
+ }
+}
+
+void chown(const std::string& path, uid_t uid, gid_t gid)
+{
+ // set owner
+ if (::chown(path.c_str(), uid, gid) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": chown() failed", errno);
+ }
+}
+
+void lchown(const std::string& path, uid_t uid, gid_t gid)
+{
+ // set owner of a symlink
+ if (::lchown(path.c_str(), uid, gid) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": lchown() failed", errno);
+ }
+}
+
+void chmod(const std::string& path, mode_t mode)
+{
+ if (::chmod(path.c_str(), mode) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": chmod() failed", errno);
+ }
+}
+
+void link(const std::string& src, const std::string& dst)
+{
+ if (::link(src.c_str(), dst.c_str()) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("path=host:" << src << ": failed to hard link to path=host:" << dst, errno);
+ }
+}
+
+void symlink(const std::string& target, const std::string& linkpath)
+{
+ if (::symlink(target.c_str(), linkpath.c_str()) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(target << ": symlink(" << linkpath << ") failed", errno);
+ }
+}
+
+void fchdir(int fd)
+{
+ if (::fchdir(fd) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("fd:" << std::to_string(fd) << ": fchdir() failed", errno);
+ }
+}
+
+void chdir(const std::string& path)
+{
+ if (::chdir(path.c_str()) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": chdir() failed", errno);
+ }
+}
+
+bool mkdir(const std::string& path, mode_t mode)
+{
+ if (::mkdir(path.c_str(), mode) == -1) {
+ if (errno == EEXIST) {
+ return false;
+ }
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": mkdir() failed", errno);
+ }
+ return true;
+}
+
+bool rmdir(const std::string& path)
+{
+ if (::rmdir(path.c_str()) == -1) {
+ if (errno == ENOENT) {
+ LOGW(path << ": not removed, directory does not exist");
+ return false;
+ }
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": failed to rmdir", errno);
+ }
+
+ return true;
+}
+
+void mknod(const std::string& path, mode_t mode, dev_t dev)
+{
+ if (::mknod(path.c_str(), mode, dev) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": mknod() failed", errno);
+ }
+}
+
+void pivot_root(const std::string& new_root, const std::string& put_old)
+{
+ if (::syscall(SYS_pivot_root, new_root.c_str(), put_old.c_str()) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(new_root << ": pivot_root() failed", errno);
}
- return result;
}
-bool readFileContent(const std::string& path, std::string& result)
+
+// ------------------- higher level functions -------------------
+std::string readFileStream(const std::string& path)
{
std::ifstream file(path);
if (!file) {
- LOGD(path << ": could not open for reading");
- return false;
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": read failed", errno);
+ }
+ // 2 x faster then std::istreambuf_iterator
+ std::stringstream content;
+ content << file.rdbuf();
+ return content.str();
+}
+
+std::string readFileContent(const std::string& path)
+{
+ std::ifstream file(path);
+
+ if (!file) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": could not open for reading", errno);
}
file.seekg(0, std::ios::end);
std::streampos length = file.tellg();
if (length < 0) {
- LOGD(path << ": tellg failed");
- return false;
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": tellg failed", errno);
}
+ std::string result;
result.resize(static_cast<size_t>(length));
file.seekg(0, std::ios::beg);
file.read(&result[0], length);
if (!file) {
- LOGD(path << ": read error");
- result.clear();
- return false;
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": read error", errno);
}
-
- return true;
+ return result;
}
-bool saveFileContent(const std::string& path, const std::string& content)
+void saveFileContent(const std::string& path, const std::string& content)
{
std::ofstream file(path);
if (!file) {
- LOGD(path << ": could not open for writing");
- return false;
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": could not open for writing", errno);
}
file.write(content.data(), static_cast<std::streamsize>(content.size()));
if (!file) {
- LOGD(path << ": could not write to");
- return false;
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": could not write to", errno);
}
- return true;
}
-bool readFirstLineOfFile(const std::string& path, std::string& ret)
+void readFirstLineOfFile(const std::string& path, std::string& ret)
{
std::ifstream file(path);
if (!file) {
- LOGD(path << ": could not open for reading");
- return false;
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": could not open for reading", errno);
}
std::getline(file, ret);
if (!file) {
- LOGD(path << ": read error");
- return false;
- }
- return true;
-}
-
-bool removeFile(const std::string& path)
-{
- if (::remove(path.c_str())) {
- if (errno != ENOENT) {
- LOGE(path << ": failed to delete: " << getSystemErrorMessage());
- return false;
- }
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": read error", errno);
}
- LOGD(path << ": successfuly removed.");
-
- return true;
}
bool exists(const std::string& path, int inodeType)
try {
assertExists(path, inodeType);
return true;
- } catch(...) {
+ } catch(const UtilsException &) {
return false;
}
}
void assertExists(const std::string& path, int inodeType)
{
if (path.empty()) {
- const std::string msg = "Empty path";
- LOGE(msg);
- throw UtilsException(msg);
- }
-
- struct stat s;
- if (::stat(path.c_str(), &s)) {
- const std::string msg = "Error in stat() " + path + ": " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_E("Empty path");
}
+ struct stat s = utils::stat(path);
if (inodeType != 0) {
if (!(s.st_mode & inodeType)) {
- const std::string msg = "Not an expected inode type, expected: " + std::to_string(inodeType) +
- ", while actual: " + std::to_string(s.st_mode);
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_E(path << ": not an expected inode type, expected: " << std::to_string(inodeType) <<
+ ", while actual: " << std::to_string(s.st_mode));
}
- if (inodeType == S_IFDIR && ::access(path.c_str(), X_OK) < 0) {
- const std::string msg = "Not a traversable directory";
- LOGE(msg);
- throw UtilsException(msg);
+ if (inodeType == S_IFDIR && !utils::access(path, X_OK)) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": not a traversable directory", errno);
}
}
}
void assertIsAbsolute(const std::string& path)
{
if (!isAbsolute(path)) {
- const std::string msg = "Given path '" + path + "' must be absolute!";
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_D(path << ": must be absolute!");
}
}
const std::string RUN_MOUNT_POINT_OPTIONS_NO_SMACK = "mode=755";
const unsigned long RUN_MOUNT_POINT_FLAGS = MS_NOSUID | MS_NODEV | MS_STRICTATIME;
-bool mountTmpfs(const std::string& path, unsigned long flags, const std::string& options)
+int mountTmpfs(const std::string& path, unsigned long flags, const std::string& options)
{
- if (::mount("tmpfs", path.c_str(), "tmpfs", flags, options.c_str()) != 0) {
- LOGD("Mount failed for '" << path << "', options=" << options << ": " << getSystemErrorMessage());
- return false;
+ try {
+ utils::mount("tmpfs", path.c_str(), "tmpfs", flags, options.c_str());
+ return 0;
+ } catch(const UtilsException & e) {
+ return e.mErrno;
}
- return true;
}
} // namespace
-bool mountRun(const std::string& path)
-{
- return utils::mountTmpfs(path, RUN_MOUNT_POINT_FLAGS, RUN_MOUNT_POINT_OPTIONS)
- || utils::mountTmpfs(path, RUN_MOUNT_POINT_FLAGS, RUN_MOUNT_POINT_OPTIONS_NO_SMACK);
-}
-
-bool mount(const std::string& source,
- const std::string& target,
- const std::string& filesystemtype,
- unsigned long mountflags,
- const std::string& data)
+void mountRun(const std::string& path)
{
- int ret = ::mount(source.c_str(),
- target.c_str(),
- filesystemtype.c_str(),
- mountflags,
- data.c_str());
- if (ret < 0) {
- LOGE("Mount operation failure: "
- << "source path: "
- << source
- << ", target path: "
- << target
- << ", filesystemtype: "
- << filesystemtype
- << ", mountflags: "
- << mountflags
- << ", data: "
- << data
- << ", msg: "
- << getSystemErrorMessage());
- return false;
+ if (utils::mountTmpfs(path, RUN_MOUNT_POINT_FLAGS, RUN_MOUNT_POINT_OPTIONS)) {
+ int errno_ = utils::mountTmpfs(path, RUN_MOUNT_POINT_FLAGS, RUN_MOUNT_POINT_OPTIONS_NO_SMACK);
+ if (errno_) {
+ THROW_UTILS_EXCEPTION_ERRNO_E(path << ": mount failed", errno_);
+ }
}
- return true;
}
-bool umount(const std::string& path)
+bool isMountPoint(const std::string& path)
{
- if (::umount(path.c_str()) != 0) {
- LOGE("Umount failed for '" << path << "': " << getSystemErrorMessage());
- return false;
- }
- return true;
+ std::string parentPath = dirName(path);
+ return ! hasSameMountPoint(path, parentPath);
}
-bool isMountPoint(const std::string& path, bool& result)
+
+bool isMountPointShared(const std::string& path)
{
- std::string parentPath = dirName(path);
- bool newResult;
- if (!hasSameMountPoint(path, parentPath, newResult)) {
- LOGE("Failed to check the files' mount points");
- return false;
+ std::ifstream fileStream("/proc/self/mountinfo");
+ if (!fileStream.good()) {
+ THROW_UTILS_EXCEPTION_E(path << ": open failed");
}
- result = !newResult;
- return true;
-}
+ // Find the line corresponding to the path
+ std::string line;
+ while (std::getline(fileStream, line).good()) {
+ std::istringstream iss(line);
+ auto it = std::istream_iterator<std::string>(iss);
+ std::advance(it, 4);
-bool hasSameMountPoint(const std::string& path1, const std::string& path2, bool& result)
-{
- struct stat s1, s2;
-
- if (::stat(path1.c_str(), &s1)) {
- LOGD("Failed to get stat of " << path1 << ": " << getSystemErrorMessage());
- return false;
- }
+ if (it->compare(path)) {
+ // Wrong line, different path
+ continue;
+ }
- if (::stat(path2.c_str(), &s2)) {
- LOGD("Failed to get stat of " << path2 << ": " << getSystemErrorMessage());
- return false;
+ // Right line, check if mount point shared
+ std::advance(it, 2);
+ return it->find("shared:") != std::string::npos;
}
- result = (s1.st_dev == s2.st_dev);
- return true;
+ // Path not found
+ return false;
}
-bool moveFile(const std::string& src, const std::string& dst)
+bool hasSameMountPoint(const std::string& path1, const std::string& path2)
{
- bool bResult;
-
- boost::system::error_code error;
+ return utils::stat(path1).st_dev == utils::stat(path2).st_dev;
+}
+void moveFile(const std::string& src, const std::string& dst)
+{
// The destination has to be a full path (including a file name)
// so it doesn't exist yet, we need to check upper level dir instead.
- if (!hasSameMountPoint(src, dirName(dst), bResult)) {
- LOGE("Failed to check the files' mount points");
- return false;
- }
+ bool bResult = hasSameMountPoint(src, dirName(dst));
if (bResult) {
+ boost::system::error_code error;
fs::rename(src, dst, error);
if (error) {
- LOGE("Failed to rename the file: " << error);
- return false;
+ THROW_UTILS_EXCEPTION_E(src << ": failed to rename to: " << dst << ", error: " << error.message());
}
} else {
- fs::copy_file(src, dst, error);
- if (error) {
- LOGE("Failed to copy the file: " << error);
- return false;
- }
- fs::remove(src, error);
- if (error) {
- LOGE("Failed to remove the file: " << error);
- fs::remove(dst, error);
- return false;
- }
+ copyFile(src, dst);
+ utils::remove(src);
}
-
- return true;
}
namespace {
}
// change owner
- struct stat info;
- ::stat(current.string().c_str(), &info);
+ struct stat info = utils::stat(current.string());
if (fs::is_symlink(destination)) {
- if (::lchown(destination.string().c_str(), info.st_uid, info.st_gid) < 0) {
- LOGW("Failed to change owner of symlink " << destination.string() << ": " << getSystemErrorMessage());
- }
+ utils::lchown(destination.string(), info.st_uid, info.st_gid);
} else {
- if (::chown(destination.string().c_str(), info.st_uid, info.st_gid) < 0) {
- LOGW("Failed to change owner of file " << destination.string() << ": " << getSystemErrorMessage());
- }
+ utils::chown(destination.string(), info.st_uid, info.st_gid);
}
}
- } catch (fs::filesystem_error& e) {
+ return true;
+ } catch (const UtilsException& e) {
+ LOGW(e.what());
+ } catch (const fs::filesystem_error& e) {
LOGW(e.what());
}
- return true;
+ return false;
}
boost::filesystem::perms getPerms(const mode_t& mode)
return static_cast<boost::filesystem::perms>(mode);
}
-bool copySmackLabel(const std::string& /* src */, const std::string& /* dst */)
-{
- //TODO: fill copySmackLabel function
- return true;
-}
-
-
} // namespace
-bool copyDirContents(const std::string& src, const std::string& dst)
+void copyDirContents(const std::string& src, const std::string& dst)
{
- return copyDirContentsRec(fs::path(src), fs::path(dst));
+ if (!copyDirContentsRec(fs::path(src), fs::path(dst))) {
+ THROW_UTILS_EXCEPTION_E(src << ": failed to copy contents to new location: " << dst);
+ }
}
-bool createDir(const std::string& path, uid_t uid, uid_t gid, boost::filesystem::perms mode)
+void createDir(const std::string& path, uid_t uid, uid_t gid, boost::filesystem::perms mode)
{
fs::path dirPath(path);
boost::system::error_code errorCode;
bool runDirCreated = false;
if (!fs::exists(dirPath)) {
if (!fs::create_directory(dirPath, errorCode)) {
- LOGE("Failed to create directory '" << path << "': "
- << errorCode.message());
- return false;
+ THROW_UTILS_EXCEPTION_E(path << ": failed to create directory, error: " << errorCode.message());
}
runDirCreated = true;
} else if (!fs::is_directory(dirPath)) {
- LOGE("Path '" << path << " already exists");
- return false;
+ THROW_UTILS_EXCEPTION_E(path << ": cannot create directory, already exists!");
}
// set permissions
fs::permissions(dirPath, mode, errorCode);
if (fs::status(dirPath).permissions() != mode) {
- LOGE("Failed to set permissions to '" << path << "': "
- << errorCode.message());
- return false;
+ THROW_UTILS_EXCEPTION_E(path << ": failed to set permissions, error: " << errorCode.message());
}
// set owner
- if (::chown(path.c_str(), uid, gid) != 0) {
- int err = errno;
- // remove the directory only if it hadn't existed before
+ try {
+ utils::chown(path, uid, gid);
+ } catch(...) {
if (runDirCreated) {
fs::remove(dirPath);
}
- LOGE("chown() failed for path '" << path << "': " << getSystemErrorMessage(err));
- return false;
+ throw;
}
-
- return true;
}
-bool createDirs(const std::string& path, mode_t mode)
+void createDirs(const std::string& path, mode_t mode)
{
const boost::filesystem::perms perms = getPerms(mode);
std::vector<fs::path> dirsCreated;
for (const auto& dirSegment : dirPath) {
prefix /= dirSegment;
if (!fs::exists(prefix)) {
- bool created = createDir(prefix.string(), -1, -1, perms);
- if (created) {
+ try {
+ createDir(prefix.string(), -1, -1, perms);
dirsCreated.push_back(prefix);
- } else {
- LOGE("Failed to create dir");
+ } catch(...) {
+ LOGE("Failed to create dir: " << prefix);
// undo
for (auto iter = dirsCreated.rbegin(); iter != dirsCreated.rend(); ++iter) {
boost::system::error_code errorCode;
<< ", msg: " << errorCode.message());
}
}
- return false;
+ throw;
}
}
}
- return true;
}
-bool createEmptyDir(const std::string& path)
+void createEmptyDir(const std::string& path)
{
fs::path dirPath(path);
boost::system::error_code ec;
if (!fs::exists(dirPath)) {
if (!fs::create_directory(dirPath, ec)) {
- LOGE("Failed to create dir. Error: " << ec.message());
- return false;
+ THROW_UTILS_EXCEPTION_E(dirPath.string() << ": failed to create dir, error: " << ec.message());
}
cleanDirCreated = true;
} else if (!fs::is_directory(dirPath)) {
- LOGE("Provided path already exists and is not a dir, cannot create.");
- return false;
+ THROW_UTILS_EXCEPTION_E(dirPath.string() << ": already exists and is not a dir, cannot create.");
}
if (!cleanDirCreated) {
// check if directory is empty if it was already created
if (!fs::is_empty(dirPath)) {
- LOGE("Directory has some data inside, cannot be used.");
- return false;
+ THROW_UTILS_EXCEPTION_E(dirPath.string() << ": directory has some data inside, cannot be used.");
}
}
-
- return true;
}
-bool createFile(const std::string& path, int flags, mode_t mode)
+void createFile(const std::string& path, int flags, mode_t mode)
{
- int ret = ::open(path.c_str(), flags, mode);
- if (ret < 0) {
- LOGE("Failed to create file: path=host:"
- << path
- << ", msg: "
- << getSystemErrorMessage());
- return false;
- }
- close(ret);
- return true;
+ utils::close(utils::open(path, O_CREAT | flags, mode));
}
-bool createFifo(const std::string& path, mode_t mode)
+void createFifo(const std::string& path, mode_t mode)
{
- int ret = ::mkfifo(path.c_str(), mode);
- if (ret < 0) {
- LOGE("Failed to make fifo: path=host:" << path);
- return false;
- }
- return true;
+ utils::mkfifo(path.c_str(), mode);
}
-bool copyFile(const std::string& src, const std::string& dest)
+void copyFile(const std::string& src, const std::string& dest)
{
boost::system::error_code errorCode;
fs::copy_file(src, dest, errorCode);
if (errorCode) {
- LOGE("Failed to copy file: msg: "
- << errorCode.message()
- << ", path=host:"
- << src
- << ", path=host:"
- << dest);
- return false;
+ THROW_UTILS_EXCEPTION_E("path=host:" << src << ": failed to copy file to path=host:"
+ << dest << ", error: " << errorCode.message());
}
- bool retSmack = copySmackLabel(src, dest);
- if (!retSmack) {
- LOGE("Failed to copy file: msg: (can't copy smacklabel) "
- << ", path=host:"
- << src
- << ", path=host:"
- << dest);
+ try {
+ copySmackLabel(src, dest);
+ } catch(const UtilsException & e) {
+ std::string msg = "Failed to copy file: msg: (can't copy smacklabel), path=host:"
+ + src
+ + ", path=host:"
+ + dest + ".";
fs::remove(src, errorCode);
if (errorCode) {
- LOGE("Failed to clean after copy failure: path=host:"
- << src
- << ", msg: "
- << errorCode.message());
+ msg += "\nFailed to clean after copy failure: path=host:"
+ + src
+ + ", msg: "
+ + errorCode.message();
}
- return false;
+ THROW_UTILS_EXCEPTION_ERRNO_E(msg, e.mErrno);
}
- return true;
}
-bool createLink(const std::string& src, const std::string& dest)
+void createLink(const std::string& src, const std::string& dest)
{
- int retLink = ::link(src.c_str(), dest.c_str());
- if (retLink < 0) {
- LOGE("Failed to hard link: path=host:"
- << src
- << ", path=host:"
- << dest
- << ", msg:"
- << getSystemErrorMessage());
- return false;
- }
- bool retSmack = copySmackLabel(src, dest);
- if (!retSmack) {
- LOGE("Failed to copy smack label: path=host:"
- << src
- << ", path=host:"
- << dest);
+ utils::link(src, dest);
+ try {
+ copySmackLabel(src, dest, false);
+ } catch(const UtilsException & e) {
+ std::string msg = "Failed to copy smack label: path=host:"
+ + src
+ + ", path=host:"
+ + dest + ".";
boost::system::error_code ec;
fs::remove(dest, ec);
if (!ec) {
- LOGE("Failed to clean after hard link creation failure: path=host:"
- << src
- << ", to: "
- << dest
- << ", msg: "
- << ec.message());
+ msg += "\nFailed to clean after hard link creation failure: path=host:"
+ + src
+ + ", to: "
+ + dest
+ + ", msg: "
+ + ec.message();
}
- return false;
+ THROW_UTILS_EXCEPTION_ERRNO_E(msg, e.mErrno);
}
- return true;
}
+
} // namespace utils
#define COMMON_UTILS_FS_HPP
#include <string>
+#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/vfs.h>
#include <vector>
#include <boost/filesystem.hpp>
namespace utils {
+// syscall wrappers
+// Throw exception on error
+
+// remove file/dir (not recursive)
+// returns true if removed, false otherwise
+bool remove(const std::string& path);
+struct ::stat stat(const std::string& path);
+struct ::statfs statfs(const std::string& path);
+// true if can be accessed with given mode
+bool access(const std::string& path, int mode);
+void mount(const std::string& source,
+ const std::string& target,
+ const std::string& filesystemtype,
+ unsigned long mountflags,
+ const std::string& data);
+void umount(const std::string& path, int flags = 0);
+// returns descriptor to the newly created item
+void mkfifo(const std::string& path, mode_t mode);
+void chown(const std::string& path, uid_t uid, gid_t gid);
+void lchown(const std::string& path, uid_t uid, gid_t gid);
+void chown(const std::string& path, uid_t owner, gid_t group);
+void link(const std::string& src, const std::string& dst);
+void symlink(const std::string& target, const std::string& linkpath);
+void fchdir(int fd);
+void chdir(const std::string& path);
+// returns true if new dir created, false if dir was already present
+bool mkdir(const std::string& path, mode_t mode);
+// returns true if removed, false otherwise
+bool rmdir(const std::string& path);
+void mknod(const std::string& path, mode_t mode, dev_t dev);
+void chmod(const std::string& path, mode_t mode);
+void pivot_root(const std::string& new_root, const std::string& put_old);
+
+
/**
* Reads the content of file stream (no seek); Throws exception on error
*/
std::string readFileStream(const std::string& path);
-/**
- * Reads the content of file stream (no seek)
- */
-bool readFileStream(const std::string& path, std::string& result);
-
/**
* Reads the content of a file (performs seek); Throws exception on error
*/
std::string readFileContent(const std::string& path);
-/**
- * Reads the content of a file
- */
-bool readFileContent(const std::string& path, std::string& content);
-
/**
* Save the content to the file
*/
-bool saveFileContent(const std::string& path, const std::string& content);
+void saveFileContent(const std::string& path, const std::string& content);
/**
* Read a line from file
- * Its goal is to read a kernel config files (eg. from /proc, /sys/)
+ * Its goal is to read a kernel config files (eg. from /proc, /sys/).
+ * Throws exception on error
*/
-bool readFirstLineOfFile(const std::string& path, std::string& ret);
-
-/**
- * Remove file
- */
-bool removeFile(const std::string& path);
+void readFirstLineOfFile(const std::string& path, std::string& ret);
/**
* Checks if a path exists and points to an expected item type.
void assertIsAbsolute(const std::string& path);
/**
- * List all (including '.' and '..' entries) dir entries
+ * Mounts run as a tmpfs on a given path.
+ * Throws exception on error
*/
-bool listDir(const std::string& path, std::vector<std::string>& files);
+void mountRun(const std::string& path);
/**
- * Mounts run as a tmpfs on a given path
+ * Check if given path is a mount point.
+ * Throws exception on error.
+ * @return boolean result
*/
-bool mountRun(const std::string& path);
+bool isMountPoint(const std::string& path);
/**
- * Creates mount point
- */
-bool mount(const std::string& source,
- const std::string& target,
- const std::string& filesystemtype,
- unsigned long mountflags,
- const std::string& data);
-
-/**
- * Umounts a filesystem
- */
-bool umount(const std::string& path);
-
-/**
- * Check if given path is a mount point
+ * Detect whether path is mounted as MS_SHARED.
+ * Parses /proc/self/mountinfo
+ * Throws exception on error.
+ *
+ * @param path mount point
+ * @return is the mount point shared
*/
-bool isMountPoint(const std::string& path, bool& result);
+bool isMountPointShared(const std::string& path);
/**
- * Checks whether the given paths are under the same mount point
+ * Checks whether the given paths are under the same mount point.
+ * Throws exception on error.
+ * @return boolean result
*/
-bool hasSameMountPoint(const std::string& path1, const std::string& path2, bool& result);
+bool hasSameMountPoint(const std::string& path1, const std::string& path2);
/**
* Moves the file either by rename if under the same mount point
* or by copy&delete if under a different one.
* The destination has to be a full path including file name.
+ * Throws exception on error
*/
-bool moveFile(const std::string& src, const std::string& dst);
+void moveFile(const std::string& src, const std::string& dst);
/**
* Recursively copy contents of src dir to dst dir.
+ * Throws exception on error
*/
-bool copyDirContents(const std::string& src, const std::string& dst);
+void copyDirContents(const std::string& src, const std::string& dst);
/**
* Creates a directory with specific UID, GID and permissions set.
+ * Throws exception on error
*/
-bool createDir(const std::string& path, uid_t uid, uid_t gid, boost::filesystem::perms mode);
+void createDir(const std::string& path, uid_t uid, uid_t gid, boost::filesystem::perms mode);
/**
* Recursively creates a directory with specific permissions set.
+ * Throws exception on error
*/
-bool createDirs(const std::string& path, mode_t mode);
+void createDirs(const std::string& path, mode_t mode);
/**
* Creates an empty directory, ready to serve as mount point.
* Succeeds either if path did not exist and was created successfully, or if already existing dir
* under the same path is empty and is not a mount point.
+ * Throws exception on error
*/
-bool createEmptyDir(const std::string& path);
+void createEmptyDir(const std::string& path);
/**
- * Creates an empty file
+ * Creates an empty file.
+ * Throws exception on error
*/
-bool createFile(const std::string& path, int flags, mode_t mode);
+void createFile(const std::string& path, int flags, mode_t mode);
/**
- * Creates an FIFO special file
+ * Creates an FIFO special file.
+ * Throws exception on error
*/
-bool createFifo(const std::string& path, mode_t mode);
+void createFifo(const std::string& path, mode_t mode);
/**
- * Copy an file
+ * Copy an file.
+ * Throws exception on error
*/
-bool copyFile(const std::string& src, const std::string& dest);
+void copyFile(const std::string& src, const std::string& dest);
/**
* Create hard link
+ * Throws exception on error.
*/
-bool createLink(const std::string& src, const std::string& dest);
+void createLink(const std::string& src, const std::string& dest);
+
} // namespace utils
#include "logger/logger.hpp"
#include "utils/img.hpp"
#include "utils/fs.hpp"
+#include "utils/fd-utils.hpp"
#include "utils/paths.hpp"
#include "utils/exception.hpp"
// Writes to ret if loop device (provided in loopdev arg) is free to use.
// Returns true if check was successful, false if loop device FD was unavailable for some reason.
+// FIXME: function prone to races
bool isLoopDevFree(const std::string& loopdev, bool& ret)
{
+ int loopFD = -1;
// initialize
ret = false;
- // open loop device FD
- int loopFD = ::open(loopdev.c_str(), O_RDWR);
- if (loopFD < 0) {
- LOGD("Failed to open loop device descriptor: " << getSystemErrorMessage());
+ try
+ {
+ // open loop device FD
+ loopFD = utils::open(loopdev, O_RDWR);
+
+ // if ioctl with LOOP_GET_STATUS fails, device is not assigned and free to use
+ struct loop_info linfo;
+ try {
+ utils::ioctl(loopFD, LOOP_GET_STATUS, &linfo);
+ } catch(const UtilsException& e) {
+ ret = true;
+ }
+ } catch(const UtilsException& e) {
+ LOGE(loopdev << " error: " << e.what());
+ utils::close(loopFD);
return false;
}
- // if ioctl with LOOP_GET_STATUS fails, device is not assigned and free to use
- struct loop_info linfo;
- if (::ioctl(loopFD, LOOP_GET_STATUS, &linfo)) {
- ret = true;
- }
-
- ::close(loopFD);
+ utils::close(loopFD);
return true;
}
unsigned long flags,
const std::string& options)
{
- // to mount an image, we need to connect image FD with loop device FD
- // get image file FD
- int fileFD = ::open(img.c_str(), O_RDWR);
- if (fileFD < 0) {
- LOGD("Failed to open image file descriptor: " << getSystemErrorMessage());
- return false;
- }
+ int fileFD = -1, loopFD = -1;
- // get loop device FD
- int loopFD = ::open(loopdev.c_str(), O_RDWR);
- if (loopFD < 0) {
- LOGD("Failed to open loop device descriptor: " << getSystemErrorMessage());
- ::close(fileFD);
- return false;
- }
+ try
+ {
+ // to mount an image, we need to connect image FD with loop device FD
+ // get image file FD
+ fileFD = utils::open(img, O_RDWR);
- // set loop device
- if (::ioctl(loopFD, LOOP_SET_FD, fileFD)) {
- LOGD("Failed to assign loop device to image: " << getSystemErrorMessage());
- ::close(fileFD);
- ::close(loopFD);
- return false;
- }
+ // get loop device FD
+ loopFD = utils::open(loopdev, O_RDWR);
+
+ // set loop device
+ utils::ioctl(loopFD, LOOP_SET_FD, reinterpret_cast<void*>(fileFD));
- // mount loop device to path
- if (::mount(loopdev.c_str(), path.c_str(), type.c_str(), flags, options.c_str()) != 0) {
- LOGD("Mount failed for '" << path << "', options=" << options << ": " << getSystemErrorMessage());
+ // mount loop device to path
+ utils::mount(loopdev, path, type, flags, options);
+
+ utils::close(fileFD);
+ utils::close(loopFD);
+ return true;
+ } catch(const utils::UtilsException& e) {
+ LOGE(path << " error: " << e.what());
::ioctl(loopFD, LOOP_CLR_FD, 0);
- ::close(fileFD);
- ::close(loopFD);
+ utils::close(fileFD);
+ utils::close(loopFD);
return false;
}
-
- ::close(fileFD);
- ::close(loopFD);
- return true;
}
} // namespace
// Finds first available loop device and returns its path through ret.
// Returns false if an error occurs, or if all available loop devices are taken.
+// FIXME: function prone to races
bool getFreeLoopDevice(std::string& ret)
{
for (unsigned int i = 0; i < 8; ++i) {
bool umountImage(const std::string& path, const std::string& loopdev)
{
- if (::umount(path.c_str()) != 0) {
- LOGD("Umount failed for '" << path << "': " << getSystemErrorMessage());
+ int loopFD = -1;
+
+ try
+ {
+ utils::umount(path);
+
+ // clear loop device
+ loopFD = utils::open(loopdev, O_RDWR);
+ utils::ioctl(loopFD, LOOP_CLR_FD, 0);
+ utils::close(loopFD);
+ return true;
+ } catch(const utils::UtilsException& e) {
+ LOGE(path << " error: " << e.what());
+ utils::close(loopFD);
return false;
}
-
- // clear loop device
- int loopFD = ::open(loopdev.c_str(), O_RDWR);
- if (loopFD < 0) {
- LOGD("Failed to open fd for loop device 0");
- return false;
- }
-
- if (::ioctl(loopFD, LOOP_CLR_FD, 0) < 0) {
- LOGD("Failed to clear loop device.");
- close(loopFD);
- return false;
- }
-
- close(loopFD);
- return true;
}
bool copyImageContents(const std::string& img, const std::string& dst)
return false;
}
- const std::string mountPoint = createFilePath(dirName(img), "/mp/");
- // create a mount point for copied image
- if (!createEmptyDir(mountPoint)) {
- LOGE("Cannot create mount point for copied image.");
- return false;
- }
+ std::string mountPoint;
+ try {
+ mountPoint = createFilePath(dirName(img), "/mp/");
+
+ // create a mount point for copied image
+ createEmptyDir(mountPoint);
- // create dst directory
- if (!createEmptyDir(dst)) {
- LOGE("Cannot create directory for data.");
+ // create dst directory
+ createEmptyDir(dst);
+ } catch(const utils::UtilsException & e) {
+ LOGE("Cannot copy image: " << e.what());
return false;
}
+
// find free loop device for image
std::string loopdev;
if (!utils::getFreeLoopDevice(loopdev)) {
// copy data
LOGI("Beginning image copy");
- if (!utils::copyDirContents(mountPoint, dst)) {
- LOGE("Failed to copy image.");
+ try {
+ utils::copyDirContents(mountPoint, dst);
+ } catch(const utils::UtilsException & e) {
+ LOGE("Failed to copy image: " << e.what());
utils::umountImage(mountPoint, loopdev);
LOGD("Removing already copied data");
fs::remove_all(fs::path(dst));
{
mFD = ::inotify_init1(IN_CLOEXEC);
if (mFD == -1) {
- const std::string msg = "Error in inotify_init1: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in inotify_init1()", errno);
}
mEventPoll.addFD(mFD, EPOLLIN, std::bind(&Inotify::handleInternal, this));
int watchID = ::inotify_add_watch(mFD, path.c_str(), eventMask);
if (-1 == watchID) {
- const std::string msg = "Error in inotify_add_watch: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in inotify_add_watch()", errno);
}
mHandlers.push_back({path, watchID, callback});
// Unwatch the path
if (-1 == ::inotify_rm_watch(mFD, it->watchID)) {
- const std::string msg = "Error in inotify_rm_watch: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in inotify_rm_watch()", errno);
}
mHandlers.erase(it);
namespace utils {
-namespace {
+// ------------------- syscall wrappers -------------------
+void pthread_sigmask(int how, const ::sigset_t *set, ::sigset_t *get)
+{
+ int ret = ::pthread_sigmask(how, set, get);
+ if (ret != 0) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in pthread_sigmask()", ret);
+ }
+}
-void setSignalMask(int how, const ::sigset_t& set)
+void sigemptyset(::sigset_t *set)
{
- int ret = ::pthread_sigmask(how, &set, nullptr /*&oldSet*/);
- if(ret != 0) {
- const std::string msg = "Error in pthread_sigmask: " + getSystemErrorMessage(ret);
- LOGE(msg);
- throw UtilsException(msg);
+ if (::sigemptyset(set) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in sigemptyset()", errno);
}
}
-void changeSignal(int how, const int sigNum) {
- ::sigset_t set;
- if(-1 == ::sigemptyset(&set)) {
- const std::string msg = "Error in sigemptyset: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+void sigfillset(::sigset_t *set)
+{
+ if(-1 == ::sigfillset(set)) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in sigfillset()", errno);
}
+}
- if(-1 ==::sigaddset(&set, sigNum)) {
- const std::string msg = "Error in sigaddset: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+void sigaddset(::sigset_t *set, int signum)
+{
+ if (::sigaddset(set, signum) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in sigaddset()", errno);
}
+}
+
+void sigpending(::sigset_t *set)
+{
+ if (::sigpending(set) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in sigpending()", errno);
+ }
+}
+
+bool sigismember(const ::sigset_t *set, int signum)
+{
+ int ret = ::sigismember(set, signum);
+ if (ret == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in sigismember()", errno);
+ }
+ return ret == 1;
+}
+
+int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout)
+{
+ int ret = ::sigtimedwait(set, info, timeout);
+ if (ret == -1) {
+ if (errno == EAGAIN) {
+ return 0;
+ }
+
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in sigtimedwait()", errno);
+ }
+ return ret;
+}
- setSignalMask(how, set);
+void sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
+{
+ if(-1 == ::sigaction(signum, act, oldact)) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in sigaction()", errno);
+ }
}
+namespace {
+void changeSignal(int how, const int sigNum) {
+ ::sigset_t set;
+ utils::sigemptyset(&set);
+ utils::sigaddset(&set, sigNum);
+ utils::pthread_sigmask(how, &set, nullptr);
+}
}// namespace
+// ------------------- higher level functions -------------------
::sigset_t getSignalMask()
{
::sigset_t set;
- int ret = ::pthread_sigmask(0 /*ignored*/, nullptr /*get the oldset*/, &set);
- if(ret != 0) {
- const std::string msg = "Error in pthread_sigmask: " + getSystemErrorMessage(ret);
- LOGE(msg);
- throw UtilsException(msg);
- }
+ utils::pthread_sigmask(0 /*ignored*/, nullptr /*get the oldset*/, &set);
return set;
}
bool isSignalPending(const int sigNum)
{
::sigset_t set;
- if (::sigpending(&set) == -1) {
- const std::string msg = "Error in sigpending: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
- }
+ utils::sigpending(&set);
- int ret = ::sigismember(&set, sigNum);
- if (ret == -1) {
- const std::string msg = "Error in sigismember: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
- }
-
- return ret;
+ return utils::sigismember(&set, sigNum);
}
bool waitForSignal(const int sigNum, int timeoutMs)
};
::sigset_t set;
- if(-1 == ::sigemptyset(&set)) {
- const std::string msg = "Error in sigemptyset: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
- }
-
- if(-1 ==::sigaddset(&set, sigNum)) {
- const std::string msg = "Error in sigaddset: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
- }
+ utils::sigemptyset(&set);
+ utils::sigaddset(&set, sigNum);
::siginfo_t info;
- if (::sigtimedwait(&set, &info, &timeout) == -1) {
- if (errno == EAGAIN) {
- return false;
- }
-
- const std::string msg = "Error in sigtimedwait: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ if(utils::sigtimedwait(&set, &info, &timeout) == 0) {
+ return false;
}
return true;
bool isSignalBlocked(const int sigNum)
{
::sigset_t set = getSignalMask();
-
- int ret = ::sigismember(&set, sigNum);
- if(-1 == ret) {
- const std::string msg = "Error in sigismember: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
- }
-
- return ret == 1;
+ return utils::sigismember(&set, sigNum);
}
void signalBlock(const int sigNum)
void signalBlockAllExcept(const std::initializer_list<int>& signals)
{
::sigset_t set;
- if(-1 == ::sigfillset(&set)) {
- const std::string msg = "Error in sigfillset: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
- }
-
+ utils::sigfillset(&set);
for(const int s: signals) {
- if(-1 == ::sigaddset(&set, s)) {
- const std::string msg = "Error in sigaddset: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
- }
+ utils::sigaddset(&set, s);
}
- setSignalMask(SIG_BLOCK, set);
+ utils::pthread_sigmask(SIG_BLOCK, &set, nullptr);
}
void signalUnblock(const int sigNum)
std::vector<std::pair<int, struct ::sigaction>> oldAct;
for(const int s: signals) {
- if(-1 == ::sigaction(s, &act, &old)) {
- const std::string msg = "Error in sigaction: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
- }
+ utils::sigaction(s, &act, &old);
oldAct.emplace_back(s, old);
}
struct ::sigaction signalSet(const int sigNum, const struct ::sigaction *sigAct)
{
struct ::sigaction old;
-
- if(-1 == ::sigaction(sigNum, sigAct, &old)) {
- const std::string msg = "Error in sigaction: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
- }
-
+ utils::sigaction(sigNum, sigAct, &old);
return old;
}
void sendSignal(const pid_t pid, const int sigNum)
{
if (-1 == ::kill(pid, sigNum)) {
- const std::string msg = "Error during killing pid: " + std::to_string(pid) +
- " sigNum: " + std::to_string(sigNum) +
- ": " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error during killing pid: " << std::to_string(pid)
+ << " sigNum: " + std::to_string(sigNum), errno);
}
}
#include <csignal>
#include <vector>
-
namespace utils {
+// ------------------- syscall wrappers -------------------
+// Throw exception on error
+void pthread_sigmask(int how, const ::sigset_t *set, ::sigset_t *get);
+void sigemptyset(::sigset_t *set);
+void sigfillset(::sigset_t *set);
+void sigaddset(::sigset_t *set, int signum);
+void sigpending(::sigset_t *set);
+bool sigismember(const ::sigset_t *set, int signum);
+int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *timeout);
+void sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
+
+// ------------------- higher level functions -------------------
::sigset_t getSignalMask();
bool isSignalPending(const int sigNum);
bool waitForSignal(const int sigNum, int timeoutMs);
namespace utils {
-SignalFD::SignalFD(cargo::ipc::epoll::EventPoll& eventPoll)
- :mEventPoll(eventPoll)
+// ------------------- syscall wrappers -------------------
+int signalfd(int fd, const sigset_t *mask, int flags)
{
- int error = ::sigemptyset(&mSet);
- if (error == -1) {
- const std::string msg = "Error in sigemptyset: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ int ret = ::signalfd(fd, mask, flags);
+ if (ret == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in signalfd()", errno);
}
+ return ret;
+}
- mFD = ::signalfd(-1, &mSet, SFD_CLOEXEC);
- if (mFD == -1) {
- const std::string msg = "Error in signalfd: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
- }
+// ------------------- higher level code -------------------
+SignalFD::SignalFD(cargo::ipc::epoll::EventPoll& eventPoll)
+ :mEventPoll(eventPoll)
+{
+ utils::sigemptyset(&mSet);
+
+ mFD = utils::signalfd(-1, &mSet, SFD_CLOEXEC);
mEventPoll.addFD(mFD, EPOLLIN, std::bind(&SignalFD::handleInternal, this));
}
mBlockedSignals.push_back(sigNum);
}
- int error = ::sigaddset(&mSet, sigNum);
- if (error == -1) {
- const std::string msg = getSystemErrorMessage();
- LOGE("Error in signalfd: " << msg);
- if(!isBlocked) {
- signalUnblock(sigNum);
- mBlockedSignals.pop_back();
- }
- throw UtilsException("Error in signalfd: " + msg);
- }
-
- error = ::signalfd(mFD, &mSet, SFD_CLOEXEC);
- if (error != mFD) {
- const std::string msg = getSystemErrorMessage();
- LOGE("Error in signalfd: " << msg);
+ try {
+ utils::sigaddset(&mSet, sigNum);
+ utils::signalfd(mFD, &mSet, SFD_CLOEXEC);
+ } catch(...) {
if(!isBlocked) {
signalUnblock(sigNum);
mBlockedSignals.pop_back();
}
- throw UtilsException("Error in signalfd: " + msg);
+ throw;
}
mCallbacks.insert({sigNum, callback});
namespace utils {
+// ------------------- syscall wrappers -------------------
+// Throw exception on error
+int signalfd(int fd, const sigset_t *mask, int flags);
+
+// ------------------- higher level code -------------------
/**
* SignalFD takes control over handling signals
* sent to the thread.
--- /dev/null
+/*
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * @author Lukasz Pawelczyk (l.pawelczyk@samsung.com)
+ * @brief SMACK utils implementation
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include "logger/logger.hpp"
+#include "utils/exception.hpp"
+#include "utils/smack.hpp"
+#include "utils/fs.hpp"
+
+#include <sys/vfs.h>
+#include <sys/types.h>
+#include <sys/xattr.h>
+
+
+namespace utils {
+// ------------------- syscall wrappers -------------------
+std::string getxattr(const std::string &path, const std::string &name)
+{
+ char value[SMACK_LABEL_MAX_LEN + 1];
+
+ int ret = ::getxattr(path.c_str(), name.c_str(), value, sizeof(value));
+ if (ret == -1) {
+ if (errno == ENODATA) {
+ return "";
+ }
+
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in getxattr(" << path << ")", errno);
+ }
+
+ value[ret] = '\0';
+ return value;
+}
+
+std::string lgetxattr(const std::string &path, const std::string &name)
+{
+ char value[SMACK_LABEL_MAX_LEN + 1];
+
+ int ret = ::lgetxattr(path.c_str(), name.c_str(), value, sizeof(value));
+ if (ret == -1) {
+ if (errno == ENODATA) {
+ return "";
+ }
+
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in lgetxattr(" << path << ")", errno);
+ }
+
+ value[ret] = '\0';
+ return value;
+}
+
+void removexattr(const std::string &path, const std::string &name)
+{
+ if (::removexattr(path.c_str(), name.c_str()) == -1) {
+ if (errno == ENODATA) {
+ return;
+ }
+
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in removexattr(" << path << ")", errno);
+ }
+}
+
+void lremovexattr(const std::string &path, const std::string &name)
+{
+ if (::lremovexattr(path.c_str(), name.c_str()) == -1) {
+ if (errno == ENODATA) {
+ return;
+ }
+
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in lremovexattr(" << path << ")", errno);
+ }
+}
+
+void setxattr(const std::string &path, const std::string &name,
+ const std::string &value, int flags)
+{
+ if (::setxattr(path.c_str(), name.c_str(), value.c_str(), value.size(), flags) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in setxattr(" << path << ")", errno);
+ }
+}
+
+void lsetxattr(const std::string &path, const std::string &name,
+ const std::string &value, int flags)
+{
+ if (::lsetxattr(path.c_str(), name.c_str(), value.c_str(), value.size(), flags) == -1) {
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in setxattr(" << path << ")", errno);
+ }
+}
+
+
+// ------------------- higher level functions -------------------
+bool isSmackActive()
+{
+ try {
+ struct statfs sfbuf = utils::statfs(SMACK_MOUNT_PATH);
+ if ((uint32_t)sfbuf.f_type == (uint32_t)SMACK_MAGIC) {
+ return true;
+ }
+ } catch(const UtilsException & e) {}
+
+ return false;
+}
+
+bool isSmackNamespaceActive()
+{
+ return utils::exists("/proc/self/attr/label_map");
+}
+
+std::string smackXattrName(SmackLabelType type)
+{
+ switch (type) {
+ case SmackLabelType::SMACK_LABEL_ACCESS:
+ return "security.SMACK64";
+ case SmackLabelType::SMACK_LABEL_EXEC:
+ return "security.SMACK64EXEC";
+ case SmackLabelType::SMACK_LABEL_MMAP:
+ return "security.SMACK64MMAP";
+ case SmackLabelType::SMACK_LABEL_TRANSMUTE:
+ return "security.SMACK64TRANSMUTE";
+ case SmackLabelType::SMACK_LABEL_IPIN:
+ return "security.SMACK64IPIN";
+ case SmackLabelType::SMACK_LABEL_IPOUT:
+ return "security.SMACK64IPOUT";
+ default:
+ THROW_UTILS_EXCEPTION_E("Wrong SMACK label type passed");
+ }
+}
+
+std::string smackGetSelfLabel()
+{
+ return utils::readFileStream("/proc/self/attr/current");
+}
+
+std::string smackGetFileLabel(const std::string &path,
+ SmackLabelType labelType,
+ bool followLinks)
+{
+ const std::string xattrName = smackXattrName(labelType);
+
+ if (followLinks) {
+ return utils::getxattr(path, xattrName);
+ } else {
+ return utils::lgetxattr(path, xattrName);
+ }
+}
+
+void smackSetFileLabel(const std::string &path,
+ const std::string &label,
+ SmackLabelType labelType,
+ bool followLinks)
+{
+ const std::string xattrName = smackXattrName(labelType);
+
+ if (label.size() > SMACK_LABEL_MAX_LEN) {
+ THROW_UTILS_EXCEPTION_E("SMACK label too long");
+ }
+
+ if (label.empty()) {
+ if (followLinks) {
+ utils::removexattr(path, xattrName);
+ } else {
+ utils::lremovexattr(path, xattrName);
+ }
+ } else {
+ if (followLinks) {
+ utils::setxattr(path, xattrName, label, 0);
+ } else {
+ utils::lsetxattr(path, xattrName, label, 0);
+ }
+ }
+}
+
+void copySmackLabel(const std::string& src, const std::string& dst, bool resolveLink)
+{
+ smackSetFileLabel(dst, smackGetFileLabel(src, SmackLabelType::SMACK_LABEL_ACCESS, resolveLink),
+ SmackLabelType::SMACK_LABEL_ACCESS, resolveLink);
+ smackSetFileLabel(dst, smackGetFileLabel(src, SmackLabelType::SMACK_LABEL_EXEC, resolveLink),
+ SmackLabelType::SMACK_LABEL_EXEC, resolveLink);
+ smackSetFileLabel(dst, smackGetFileLabel(src, SmackLabelType::SMACK_LABEL_MMAP, resolveLink),
+ SmackLabelType::SMACK_LABEL_MMAP, resolveLink);
+ smackSetFileLabel(dst, smackGetFileLabel(src, SmackLabelType::SMACK_LABEL_TRANSMUTE, resolveLink),
+ SmackLabelType::SMACK_LABEL_TRANSMUTE, resolveLink);
+}
+
+} // namespace lxcpp
--- /dev/null
+/*
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * @author Lukasz Pawelczyk (l.pawelczyk@samsung.com)
+ * @brief SMACK utils headers
+ */
+
+#ifndef COMMON_UTILS_SMACK_HPP
+#define COMMON_UTILS_SMACK_HPP
+
+#include <string>
+
+#define SMACK_MOUNT_PATH "/sys/fs/smackfs"
+#define SMACK_LABEL_MAX_LEN 255
+
+#ifndef SMACK_MAGIC
+#define SMACK_MAGIC 0x43415d53 // "SMAC"
+#endif
+
+namespace utils {
+
+// ------------------- syscall wrappers -------------------
+// Throw exception on error
+std::string getxattr(const std::string &path, const std::string &name);
+std::string lgetxattr(const std::string &path, const std::string &name);
+void removexattr(const std::string &path, const std::string &name);
+void lremovexattr(const std::string &path, const std::string &name);
+void setxattr(const std::string &path, const std::string &name,
+ const std::string &value, int flags);
+void lsetxattr(const std::string &path, const std::string &name,
+ const std::string &value, int flags);
+
+// ------------------- higher level functions -------------------
+enum class SmackLabelType : int {
+ SMACK_LABEL_ACCESS = 0,
+ SMACK_LABEL_EXEC,
+ SMACK_LABEL_MMAP,
+ SMACK_LABEL_TRANSMUTE,
+ SMACK_LABEL_IPIN,
+ SMACK_LABEL_IPOUT,
+
+ // ---
+ SMACK_LABEL_TERMINATOR
+};
+
+bool isSmackActive();
+bool isSmackNamespaceActive();
+std::string smackXattrName(SmackLabelType type);
+std::string smackGetSelfLabel();
+std::string smackGetFileLabel(const std::string &path,
+ SmackLabelType labelType,
+ bool followLinks);
+void smackSetFileLabel(const std::string &path,
+ const std::string &label,
+ SmackLabelType labelType,
+ bool followLinks);
+void copySmackLabel(const std::string &src, const std::string &dst, bool resolveLink = true);
+
+} // namespace utils
+
+#endif // COMMON_UTILS_SMACK_HPP
{
std::unique_lock<std::mutex> lock(mMutex);
if (mValue) {
- throw UtilsException("Cannot set value multiple times");
+ THROW_UTILS_EXCEPTION_E("Cannot set value multiple times");
}
mValue.reset(new T(value));
mCondition.notify_one();
{
std::unique_lock<std::mutex> lock(mMutex);
if (mValue) {
- throw UtilsException("Cannot set value multiple times");
+ THROW_UTILS_EXCEPTION_E("Cannot set value multiple times");
}
mValue.reset(new T(std::move(value)));
mCondition.notify_one();
std::unique_ptr<T> retValue(std::move(mValue));
return T(std::move(*retValue));
} else {
- throw UtilsException("Timeout occured");
+ THROW_UTILS_EXCEPTION_E("Timeout occured");
}
}
#include "utils/vt.hpp"
#include "logger/logger.hpp"
#include "utils/exception.hpp"
+#include "utils/fd-utils.hpp"
#include <fcntl.h>
#include <sys/ioctl.h>
bool activateVT(const int& vt)
{
- int consoleFD = ::open(TTY_DEV.c_str(), O_WRONLY);
- if (consoleFD < 0) {
- LOGE("console open failed: " << errno << " (" << getSystemErrorMessage() << ")");
- return false;
- }
+ int consoleFD = -1;
- struct vt_stat vtstat;
- vtstat.v_active = 0;
- if (::ioctl(consoleFD, VT_GETSTATE, &vtstat)) {
- LOGE("Failed to get vt state: " << errno << " (" << getSystemErrorMessage() << ")");
- ::close(consoleFD);
- return false;
- }
+ try {
+ consoleFD = utils::open(TTY_DEV, O_WRONLY);
- if (vtstat.v_active == vt) {
- LOGW("vt" << vt << " is already active.");
- ::close(consoleFD);
- return true;
- }
+ struct vt_stat vtstat;
+ vtstat.v_active = 0;
+ utils::ioctl(consoleFD, VT_GETSTATE, &vtstat);
- // activate vt
- if (::ioctl(consoleFD, VT_ACTIVATE, vt)) {
- LOGE("Failed to activate vt" << vt << ": " << errno << " (" << getSystemErrorMessage() << ")");
- ::close(consoleFD);
- return false;
- }
+ if (vtstat.v_active == vt) {
+ LOGW("vt" << vt << " is already active.");
+ }
+ else {
+ // activate vt
+ utils::ioctl(consoleFD, VT_ACTIVATE, reinterpret_cast<void*>(vt));
+
+ // wait until activation is finished
+ utils::ioctl(consoleFD, VT_WAITACTIVE, reinterpret_cast<void*>(vt));
+ }
- // wait until activation is finished
- if (::ioctl(consoleFD, VT_WAITACTIVE, vt)) {
- LOGE("Failed to wait for vt" << vt << " activation: " << errno << " (" << getSystemErrorMessage() << ")");
- ::close(consoleFD);
+ utils::close(consoleFD);
+ return true;
+ } catch(const UtilsException & e) {
+ LOGE("Failed to activate vt" << vt << ": " << e.what() << " (" << getSystemErrorMessage(e.mErrno) << ")");
+ utils::close(consoleFD);
return false;
}
-
- ::close(consoleFD);
- return true;
}
} // namespace utils
: mPollFD(::epoll_create1(EPOLL_CLOEXEC))
{
if (mPollFD == -1) {
- const std::string msg = "Failed to create epoll: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in epoll_create1()", errno);
}
}
std::lock_guard<Mutex> lock(mMutex);
if (mCallbacks.find(fd) != mCallbacks.end()) {
- const std::string msg = "fd " + std::to_string(fd) + " already added";
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_E("fd " << std::to_string(fd) << " already added");
}
if (!addFDInternal(fd, events)) {
- const std::string msg = "Could not add fd";
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_E("Could not add fd");
}
mCallbacks.insert({fd, std::make_shared<Callback>(std::move(callback))});
{
// No need to lock as modify doesn't touch the mCallbacks map
if (!modifyFDInternal(fd, events)) {
- const std::string msg = "Could not modify fd: " + std::to_string(fd);
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_E("Could not modify fd: " << std::to_string(fd));
}
}
if (errno == EINTR) {
continue;
}
- const std::string msg = "Failed to wait on epoll: " + getSystemErrorMessage();
- LOGE(msg);
- throw UtilsException(msg);
+ THROW_UTILS_EXCEPTION_ERRNO_E("Error in epoll_wait()", errno);
}
// callback could be removed in the meantime, so be careful, find it inside lock
MESSAGE(STATUS "")
MESSAGE(STATUS "Generating makefile for the lib${PROJECT_NAME}...")
-FILE(GLOB SRCS internals/*.cpp)
+FILE(GLOB HEADERS *.hpp)
+FILE(GLOB HEADERS_INTERNALS internals/*.hpp)
SET(_LIB_VERSION_ "${VERSION}")
SET(_LIB_SOVERSION_ "0")
SET(PC_FILE "lib${PROJECT_NAME}.pc")
## Setup target ################################################################
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
- SOVERSION ${_LIB_SOVERSION_}
- VERSION ${_LIB_VERSION_}
-)
-
-ADD_DEPENDENCIES(${PROJECT_NAME} cargo-utils)
## Link libraries ##############################################################
PKG_SEARCH_MODULE(JSON_C REQUIRED json json-c)
INCLUDE_DIRECTORIES(${COMMON_FOLDER} ${LIBS_FOLDER})
INCLUDE_DIRECTORIES(SYSTEM ${JSON_C_INCLUDE_DIRS})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${JSON_C_LIBRARIES})
## Generate the pc file ########################################################
CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE} @ONLY)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PC_FILE}
DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
-INSTALL(TARGETS ${PROJECT_NAME}
- DESTINATION ${LIB_INSTALL_DIR}
- COMPONENT RuntimeLibraries)
-
INSTALL(DIRECTORY . DESTINATION ${INCLUDE_INSTALL_DIR}/${PROJECT_NAME}
FILES_MATCHING PATTERN "*.hpp"
PATTERN "CMakeFiles" EXCLUDE)
#ifndef CARGO_JSON_CARGO_JSON_HPP
#define CARGO_JSON_CARGO_JSON_HPP
+#include "utils/fs.hpp"
#include "cargo-json/internals/to-json-visitor.hpp"
#include "cargo-json/internals/from-json-visitor.hpp"
-#include "cargo-json/internals/fs-utils.hpp"
namespace cargo {
template <class Cargo>
void loadFromJsonFile(const std::string& filename, Cargo& visitable)
{
- std::string content;
- if (!internals::fsutils::readFileContent(filename, content)) {
- const std::string& msg = "Could not load " + filename;
- throw CargoException(msg);
- }
+ const std::string content = utils::readFileContent(filename);
try {
loadFromJsonString(content, visitable);
} catch (CargoException& e) {
void saveToJsonFile(const std::string& filename, const Cargo& visitable)
{
const std::string content = saveToJsonString(visitable);
- if (!internals::fsutils::saveFileContent(filename, content)) {
- throw CargoException("Could not save " + filename);
- }
+ utils::saveFileContent(filename, content);
}
} // namespace cargo
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact: Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
- *
- * 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
- * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
- * @brief Filesystem helper functions
- */
-
-#include "config.hpp"
-
-#include "cargo-json/internals/fs-utils.hpp"
-
-#include <fstream>
-#include <streambuf>
-
-
-namespace cargo {
-namespace internals {
-namespace fsutils {
-
-bool readFileContent(const std::string& path, std::string& result)
-{
- std::ifstream file(path);
-
- if (!file) {
- return false;
- }
-
- file.seekg(0, std::ios::end);
- std::streampos length = file.tellg();
- if (length < 0) {
- return false;
- }
- result.resize(static_cast<size_t>(length));
- file.seekg(0, std::ios::beg);
-
- file.read(&result[0], length);
- if (!file) {
- result.clear();
- return false;
- }
-
- return true;
-}
-
-bool saveFileContent(const std::string& path, const std::string& content)
-{
- std::ofstream file(path);
- if (!file) {
- return false;
- }
- file.write(content.data(), static_cast<std::streamsize>(content.size()));
- if (!file) {
- return false;
- }
- return true;
-}
-
-} // namespace fsutils
-} // namespace internals
-} // namespace cargo
+++ /dev/null
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact: Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
- *
- * 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
- * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
- * @brief src/cargo/manager.hpp
- */
-
-#ifndef CARGO_JSON_INTERNALS_FS_UTILS_HPP
-#define CARGO_JSON_INTERNALS_FS_UTILS_HPP
-
-#include <string>
-
-namespace cargo {
-namespace internals {
-namespace fsutils {
-
-bool readFileContent(const std::string& path, std::string& result);
-bool saveFileContent(const std::string& path, const std::string& content);
-
-inline std::string readFileContent(const std::string& path) {
- std::string content;
- return readFileContent(path, content) ? content : std::string();
-}
-} // namespace fsutils
-} // namespace internals
-} // namespace cargo
-
-#endif // CARGO_JSON_INTERNALS_FS_UTILS_HPP
Name: lib@PROJECT_NAME@
Description: cargo Json library
Version: @_LIB_VERSION_@
-Libs: -L${libdir} -l@PROJECT_NAME@ -l@JSON_C_LIBRARIES@
+Libs: -L${libdir} -l@JSON_C_LIBRARIES@
Cflags: -I${includedir} -I${includedir}/@PROJECT_NAME@ -I@JSON_C_INCLUDE_DIRS@
#ifndef CARGO_SQLITE_JSON_CARGO_SQLITE_JSON_HPP
#define CARGO_SQLITE_JSON_CARGO_SQLITE_JSON_HPP
+#include "utils/fs.hpp"
#include "cargo-json/internals/to-json-visitor.hpp"
#include "cargo-sqlite/internals/to-kvstore-visitor.hpp"
#include "cargo-json/internals/from-json-visitor.hpp"
#include "cargo-sqlite/internals/from-kvstore-visitor.hpp"
#include "cargo-sqlite/internals/from-kvstore-ignoring-visitor.hpp"
-#include "cargo-json/internals/fs-utils.hpp"
// TODO: remove dependencies to other libraries internals
namespace cargo {
Cargo& visitable,
const std::string& kvVisitableName)
{
- std::string content;
- if (!internals::fsutils::readFileContent(jsonfile, content)) {
- throw CargoException("Could not load " + jsonfile);
- }
+ const std::string content = utils::readFileContent(jsonfile);
try {
loadFromKVStoreWithJson(kvfile, content, visitable, kvVisitableName);
} catch (CargoException& e) {
%{_libdir}/pkgconfig/libcargo-gvariant.pc
## libcargo-json Package ######################################################
-%package -n libcargo-json
-Summary: Cargo Json module
-Group: Security/Other
-%if %{platform_type} == "TIZEN"
-BuildRequires: libjson-devel >= 0.10
-Requires: libjson >= 0.10
-%else
-BuildRequires: json-c-devel
-Requires: json-c
-%endif
-Requires(post): /sbin/ldconfig
-Requires(postun): /sbin/ldconfig
-
-%description -n libcargo-json
-The package provides libcargo Json module.
-
-%post -n libcargo-json -p /sbin/ldconfig
-
-%postun -n libcargo-json -p /sbin/ldconfig
-
-%files -n libcargo-json
-%defattr(644,root,root,755)
-%{_libdir}/libcargo-json.so.0
-%attr(755,root,root) %{_libdir}/libcargo-json.so.%{version}
-
%package -n libcargo-json-devel
Summary: Development cargo Json module
Group: Development/Libraries
Requires: libcargo-devel = %{epoch}:%{version}-%{release}
-Requires: libcargo-json = %{epoch}:%{version}-%{release}
Requires: boost-devel
Requires: pkgconfig(libLogger)
%if %{platform_type} == "TIZEN"
Requires: libjson-devel >= 0.10
+BuildRequires: libjson-devel >= 0.10
%else
Requires: json-c-devel
+BuildRequires: json-c-devel
%endif
%description -n libcargo-json-devel
%files -n libcargo-json-devel
%defattr(644,root,root,755)
-%{_libdir}/libcargo-json.so
%{_includedir}/cargo-json
%{_libdir}/pkgconfig/libcargo-json.pc
)
TARGET_LINK_LIBRARIES(${UT_SERVER_CODENAME} ${Boost_LIBRARIES}
- Logger cargo-json cargo-sqlite cargo-fd cargo-ipc cargo-validator)
+ Logger ${JSON_C_LIBRARIES} cargo-sqlite cargo-fd cargo-ipc cargo-validator)
IF(NOT WITHOUT_SYSTEMD)
SET_TARGET_PROPERTIES(${SOCKET_TEST_CODENAME} PROPERTIES
#include "cargo-ipc/epoll/glib-dispatcher.hpp"
#include "utils/channel.hpp"
#include "utils/glib-loop.hpp"
+#include "utils/fs.hpp"
#include "utils/latch.hpp"
#include "utils/value-latch.hpp"
#include "utils/scoped-dir.hpp"
const char DATA[] = "Content of the file";
{
// Fill the file
- fs::remove(TEST_FILE);
+ utils::remove(TEST_FILE);
std::ofstream file(TEST_FILE);
file << DATA;
file.close();
#include "ut.hpp"
#include "testconfig-example.hpp"
+#include "utils/fs.hpp"
+#include "utils/fd-utils.hpp"
#include "cargo-gvariant/cargo-gvariant.hpp"
#include "cargo-fd/cargo-fd.hpp"
#include "cargo-sqlite/cargo-sqlite.hpp"
loadFromJsonString(jsonTestString, config);
// Setup fd
std::string fifoPath = UT_PATH + "fdstore";
- BOOST_CHECK(::mkfifo(fifoPath.c_str(), S_IWUSR | S_IRUSR) >= 0);
+ BOOST_CHECK_NO_THROW(utils::mkfifo(fifoPath, S_IWUSR | S_IRUSR));
int fd = ::open(fifoPath.c_str(), O_RDWR);
BOOST_REQUIRE(fd >= 0);
loadFromJsonString(jsonTestString, config);
// Setup fd
std::string fifoPath = UT_PATH + "fdstore";
- BOOST_CHECK(::mkfifo(fifoPath.c_str(), S_IWUSR | S_IRUSR) >= 0);
- int fd = ::open(fifoPath.c_str(), O_RDWR);
+ BOOST_CHECK_NO_THROW(utils::mkfifo(fifoPath, S_IWUSR | S_IRUSR));
+ BOOST_REQUIRE(utils::access(fifoPath, O_RDWR));
+ int fd = utils::open(fifoPath.c_str(), O_RDWR);
BOOST_REQUIRE(fd >= 0);
// The test
BOOST_CHECK_EQUAL(out, jsonTestString);
// Cleanup
- BOOST_CHECK(::close(fd) >= 0);
+ BOOST_CHECK_NO_THROW(utils::close(fd));
}
BOOST_AUTO_TEST_CASE(FromKVWithDefaults)
BOOST_CHECK_EQUAL(REFERENCE_FILE_CONTENT, readFileContent(REFERENCE_FILE_PATH));
BOOST_CHECK_EXCEPTION(readFileContent(BUGGY_FILE_PATH),
UtilsException,
- WhatEquals("Read failed"));
+ WhatEquals(BUGGY_FILE_PATH + ": could not open for reading"));
}
BOOST_AUTO_TEST_CASE(SaveFileContent)
{
- BOOST_REQUIRE(saveFileContent(FILE_PATH, REFERENCE_FILE_CONTENT));
+ BOOST_REQUIRE_NO_THROW(saveFileContent(FILE_PATH, REFERENCE_FILE_CONTENT));
BOOST_CHECK_EQUAL(REFERENCE_FILE_CONTENT, readFileContent(FILE_PATH));
}
BOOST_AUTO_TEST_CASE(RemoveFile)
{
- BOOST_REQUIRE(saveFileContent(FILE_PATH, REFERENCE_FILE_CONTENT));
- BOOST_REQUIRE(removeFile(FILE_PATH));
+ BOOST_REQUIRE_NO_THROW(saveFileContent(FILE_PATH, REFERENCE_FILE_CONTENT));
+ BOOST_REQUIRE_EQUAL(remove(FILE_PATH), true);
BOOST_REQUIRE(!boost::filesystem::exists(FILE_PATH));
}
BOOST_AUTO_TEST_CASE(MountPoint)
{
- bool result;
namespace fs = boost::filesystem;
boost::system::error_code ec;
BOOST_REQUIRE(fs::create_directory(MOUNT_POINT_1, ec));
- BOOST_REQUIRE(isMountPoint(MOUNT_POINT_1, result));
- BOOST_CHECK_EQUAL(result, false);
- BOOST_REQUIRE(hasSameMountPoint(TEST_PATH, MOUNT_POINT_1, result));
- BOOST_CHECK_EQUAL(result, true);
-
- BOOST_REQUIRE(mountRun(MOUNT_POINT_1));
- BOOST_REQUIRE(isMountPoint(MOUNT_POINT_1, result));
- BOOST_CHECK_EQUAL(result, true);
- BOOST_REQUIRE(hasSameMountPoint(TEST_PATH, MOUNT_POINT_1, result));
- BOOST_CHECK_EQUAL(result, false);
-
- BOOST_REQUIRE(umount(MOUNT_POINT_1));
+ BOOST_REQUIRE_EQUAL(false, isMountPoint(MOUNT_POINT_1));
+ BOOST_REQUIRE_EQUAL(true, hasSameMountPoint(TEST_PATH, MOUNT_POINT_1));
+
+ BOOST_REQUIRE_NO_THROW(mountRun(MOUNT_POINT_1));
+ BOOST_REQUIRE_EQUAL(true, isMountPoint(MOUNT_POINT_1));
+ BOOST_REQUIRE_EQUAL(false, hasSameMountPoint(TEST_PATH, MOUNT_POINT_1));
+
+ BOOST_REQUIRE_NO_THROW(utils::umount(MOUNT_POINT_1));
BOOST_REQUIRE(fs::remove(MOUNT_POINT_1, ec));
}
BOOST_AUTO_TEST_CASE(MoveFile)
{
- namespace fs = boost::filesystem;
- boost::system::error_code ec;
+ //namespace fs = boost::filesystem;
std::string src, dst;
// same mount point
src = TEST_PATH + "/" + FILE_NAME_1;
dst = TEST_PATH + "/" + FILE_NAME_2;
- BOOST_REQUIRE(saveFileContent(src, REFERENCE_FILE_CONTENT));
+ BOOST_REQUIRE_NO_THROW(saveFileContent(src, REFERENCE_FILE_CONTENT));
- BOOST_CHECK(moveFile(src, dst));
- BOOST_CHECK(!fs::exists(src));
+ BOOST_CHECK_NO_THROW(moveFile(src, dst));
+ BOOST_CHECK(!utils::exists(src));
BOOST_CHECK_EQUAL(readFileContent(dst), REFERENCE_FILE_CONTENT);
- BOOST_REQUIRE(fs::remove(dst));
+ BOOST_REQUIRE(utils::remove(dst));
// different mount point
src = TEST_PATH + "/" + FILE_NAME_1;
dst = MOUNT_POINT_2 + "/" + FILE_NAME_2;
- BOOST_REQUIRE(fs::create_directory(MOUNT_POINT_2, ec));
- BOOST_REQUIRE(mountRun(MOUNT_POINT_2));
- BOOST_REQUIRE(saveFileContent(src, REFERENCE_FILE_CONTENT));
+ BOOST_REQUIRE_NO_THROW(utils::createEmptyDir(MOUNT_POINT_2));
+ BOOST_REQUIRE_NO_THROW(mountRun(MOUNT_POINT_2));
+ BOOST_REQUIRE_NO_THROW(saveFileContent(src, REFERENCE_FILE_CONTENT));
- BOOST_CHECK(moveFile(src, dst));
- BOOST_CHECK(!fs::exists(src));
+ BOOST_CHECK_NO_THROW(moveFile(src, dst));
+ BOOST_CHECK(!utils::exists(src));
BOOST_CHECK_EQUAL(readFileContent(dst), REFERENCE_FILE_CONTENT);
- BOOST_REQUIRE(fs::remove(dst));
- BOOST_REQUIRE(umount(MOUNT_POINT_2));
- BOOST_REQUIRE(fs::remove(MOUNT_POINT_2, ec));
+ BOOST_REQUIRE(utils::remove(dst));
+ BOOST_REQUIRE_NO_THROW(utils::umount(MOUNT_POINT_2));
+ BOOST_REQUIRE_NO_THROW(utils::rmdir(MOUNT_POINT_2));
}
BOOST_AUTO_TEST_CASE(CopyDirContents)
BOOST_REQUIRE(fs::create_directory(src_inner2, ec));
BOOST_REQUIRE(ec.value() == 0);
- BOOST_REQUIRE(saveFileContent(src + "/" + FILE_NAME_1, REFERENCE_FILE_CONTENT));
- BOOST_REQUIRE(saveFileContent(src + "/" + FILE_NAME_2, FILE_CONTENT_2));
- BOOST_REQUIRE(saveFileContent(src_inner + "/" + FILE_NAME_1, FILE_CONTENT_3));
- BOOST_REQUIRE(saveFileContent(src_inner2 + "/" + FILE_NAME_1, FILE_CONTENT_3));
- BOOST_REQUIRE(saveFileContent(src_inner2 + "/" + FILE_NAME_2, FILE_CONTENT_2));
+ BOOST_REQUIRE_NO_THROW(saveFileContent(src + "/" + FILE_NAME_1, REFERENCE_FILE_CONTENT));
+ BOOST_REQUIRE_NO_THROW(saveFileContent(src + "/" + FILE_NAME_2, FILE_CONTENT_2));
+ BOOST_REQUIRE_NO_THROW(saveFileContent(src_inner + "/" + FILE_NAME_1, FILE_CONTENT_3));
+ BOOST_REQUIRE_NO_THROW(saveFileContent(src_inner2 + "/" + FILE_NAME_1, FILE_CONTENT_3));
+ BOOST_REQUIRE_NO_THROW(saveFileContent(src_inner2 + "/" + FILE_NAME_2, FILE_CONTENT_2));
// change permissions of src_inner2 directory
fs::permissions(src_inner2, fs::owner_read, ec);
BOOST_REQUIRE(ec.value() == 0);
// copy data
- BOOST_CHECK(copyDirContents(src, dst));
+ BOOST_CHECK_NO_THROW(copyDirContents(src, dst));
// check if copy is successful
BOOST_CHECK(fs::exists(dst + "/" + FILE_NAME_1));
i.setHandler(TEST_DIR, IN_DELETE, [&](const std::string& name, uint32_t) {
deleteResult.set(name);
});
- fs::remove(FILE_PATH);
+ utils::remove(FILE_PATH);
BOOST_REQUIRE_EQUAL(deleteResult.get(), FILE_NAME);
}
i.setHandler(TEST_DIR, IN_CREATE, [&](const std::string& name, uint32_t) {
createResult.set(name);
});
- fs::remove(FILE_PATH);
+ utils::remove(FILE_PATH);
BOOST_REQUIRE_THROW(createResult.get(10), UtilsException);
}
});
i.removeHandler(TEST_DIR);
utils::createFile(FILE_PATH, O_WRONLY | O_CREAT, 0666);
- fs::remove(FILE_PATH);
+ utils::remove(FILE_PATH);
BOOST_REQUIRE_THROW(createResult.get(10), UtilsException);
}