Fix pkg_initdb tool to check backend execution result
[platform/core/appfw/app-installers.git] / src / common / utils / subprocess.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/utils/subprocess.h"
6
7 #include <manifest_parser/utils/logging.h>
8
9 #include <signal.h>
10 #include <sys/types.h>
11 #include <sys/wait.h>
12 #include <unistd.h>
13
14 #include <memory>
15
16 namespace common_installer {
17
18 Subprocess::Subprocess(const std::string& program)
19     : program_(program),
20       pid_(0),
21       started_(false),
22       uid_(-1) {
23 }
24
25 bool Subprocess::RunWithArgs(const std::vector<std::string>& args) {
26   if (started_) {
27     LOG(WARNING) << "Process already started";
28     return false;
29   }
30   pid_ = fork();
31   if (pid_ == 0) {
32     std::unique_ptr<const char*[]> argv(new const char*[2 + args.size()]);
33     argv[0] = program_.c_str();
34     for (size_t i = 1; i <= args.size(); ++i) {
35       argv[i] = args[i - 1].c_str();
36     }
37     argv[args.size() + 1] = nullptr;
38     if (uid_ != -1) {
39       if (setuid(uid_)) {
40         LOG(ERROR) << "Failed to setuid";
41         return false;
42       }
43     }
44     execvp(argv[0], const_cast<char* const*>(argv.get()));
45     LOG(ERROR) << "Failed to execv";
46     return false;
47   } else if (pid_ == -1) {
48     LOG(ERROR) << "Failed to fork";
49     return false;
50   } else {
51     started_ = true;
52     return true;
53   }
54 }
55
56 bool Subprocess::Wait() {
57   if (!started_) {
58     LOG(WARNING) << "Process is not started. Cannot wait";
59     return false;
60   }
61   int status;
62   waitpid(pid_, &status, 0);
63   if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0)
64     return false;
65
66   return true;
67 }
68
69 void Subprocess::Kill() {
70   int ret = kill(pid_, SIGKILL);
71   if (ret)
72     LOG(ERROR) << "kill failed";
73 }
74
75 }  // namespace common_installer