#include <unistd.h>
#include <sys/mount.h>
#include <sys/reboot.h>
+#include <sys/wait.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
::vconf_set_bool(VCONFKEY_ODE_FAST_ENCRYPTION, value);
}
-void execAndWait(const std::string &path, std::vector<std::string> &args)
+void killProcesses(std::vector<const char*> &args)
{
- runtime::Process proc(path, args);
- int ret = proc.execute();
- if (ret < 0)
- ERROR(SINK, "Executing " + path + " failed for " + args.back());
-
- ret = proc.waitForFinished();
- if (ret < 0 || !WIFEXITED(ret) || WEXITSTATUS(ret) != 0)
- ERROR(SINK, "Waiting for " + path + " failed for " + args.back());
+ int pipeFd[2] = {0, };
+ pid_t pid = 0;
+
+ if (::pipe(pipeFd) < 0)
+ throw runtime::Exception("Failed to create pipe");
+
+ pid = ::fork();
+ if (pid < 0) {
+ ::close(pipeFd[0]);
+ ::close(pipeFd[1]);
+ throw runtime::Exception("Failed to fork");
+ }
+
+ if (pid == 0) {
+ ::close(pipeFd[0]);
+ if (::dup2(pipeFd[1], STDOUT_FILENO) < 0)
+ ERROR(SINK, "Failed to copy STDOUT_FILENO");
+
+ if (::dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
+ ERROR(SINK, "Failed to copy STDERR_FILENO");
+
+ ::close(pipeFd[1]);
+
+ if (::execv(args[0], const_cast<char* const*>(args.data())) < 0)
+ ERROR(SINK, "Failed to execute : " + std::to_string(errno));
+
+ std::quick_exit(EXIT_FAILURE);
+ }
+
+ ::close(pipeFd[1]);
+
+ for (int status = 0; ::waitpid(pid, &status, 0) == -1;) {
+ if (errno != EINTR) {
+ ::close(pipeFd[0]);
+ throw runtime::Exception("Failed to wait child process");
+ }
+ }
+
+ auto closeFile = [](FILE *fp) { ::fclose(fp); };
+ std::unique_ptr<FILE, decltype(closeFile)> fp(::fdopen(pipeFd[0], "r"), closeFile);
+ if (fp == nullptr) {
+ ::close(pipeFd[0]);
+ throw runtime::Exception("Failed to open pipe descriptor");
+ }
+
+ char *line = nullptr;
+ size_t len = 0;
+ try {
+ while ((::getline(&line, &len, fp.get())) != -1) {
+ std::string log(line);
+ log.erase(std::find_if(log.rbegin(), log.rend(),
+ std::ptr_fun<int, int>(std::isgraph)).base(), log.end());
+ WARN(SINK, log);
+ }
+ } catch (std::exception &e) {
+ ERROR(SINK, e.what());
+ }
+ ::free(line);
+ ::close(pipeFd[0]);
}
bool isPartitionTerminated(const std::string &partition)
do {
::sync();
- static const char *fuserPath = "/usr/bin/fuser";
- std::vector<std::string> args = {
- fuserPath, "-m", "-k", "-s", "-SIGTERM", source,
+ std::vector<const char*> args = {
+ "/usr/bin/fuser", "-m", "-k", "-v", "-SIGTERM", source.c_str(), nullptr
};
- execAndWait(fuserPath, args);
- ::usleep((useconds_t)((unsigned int)(500)*1000));
+ try {
+ killProcesses(args);
+ ::usleep((useconds_t)((unsigned int)(500)*1000));
- args[4] = "-SIGKILL";
- execAndWait(fuserPath, args);
- ::usleep((useconds_t)((unsigned int)(200)*1000));
+ args[4] = "-SIGKILL";
+ killProcesses(args);
+ ::usleep((useconds_t)((unsigned int)(200)*1000));
+ } catch (runtime::Exception &e) {
+ ERROR(e.what());
+ }
} while (!isPartitionTerminated(source));
}