2 * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "launchpad-process-pool/loader_executor.hh"
27 #include "launchpad-process-pool/log_private.hh"
28 #include "launchpad-process-pool/signal_manager.hh"
29 #include "lib/common/inc/launchpad_common.h"
30 #include "lib/common/inc/launchpad_types.h"
35 std::shared_ptr<AppPacket> CreateAppPacketFromArgs(
36 const std::vector<std::string>& args) {
38 b.Add("LOADER_ARGS", args);
40 std::vector<uint8_t> data(raw.first.get(), raw.first.get() + raw.second);
41 return std::shared_ptr<AppPacket>(new AppPacket(0, 0, std::move(data)));
44 std::vector<std::string> CreateArgsFromAppPacket(const AppPacket* app_packet) {
45 auto& data = app_packet->GetData();
46 std::string raw(data.begin(), data.end());
47 tizen_base::Bundle b(raw);
48 return b.GetStringArray("LOADER_ARGS");
53 LoaderExecutor::LoaderExecutor()
54 : Executor(this), process_pool_(new ProcessPool(2, this)) {}
56 LoaderExecutor& LoaderExecutor::GetInst() {
57 static LoaderExecutor inst;
61 pid_t LoaderExecutor::Execute(const LoaderContext* loader_context,
63 loader_argv_ = CreateLoaderArgv(loader_context);
64 if (process_pool_->IsPrepared()) {
65 auto app_packet = CreateAppPacketFromArgs(loader_argv_);
66 return process_pool_->Execute(std::move(app_packet));
69 return Executor::Execute(priority);
72 bool LoaderExecutor::HasCandidateProcess() const {
73 return process_pool_->IsPrepared();
76 void LoaderExecutor::DisposeCandidateProcess() {
77 process_pool_->Dispose();
78 process_pool_->SetTimer();
81 void LoaderExecutor::OnExecution() {
82 std::vector<char*> loader_argv(loader_argv_.size() + 1);
83 int loader_argc = loader_argv_.size();
84 for (int i = 0; i < loader_argc; ++i) {
85 loader_argv[i] = const_cast<char*>(loader_argv_[i].c_str());
86 if ((i + 1) != loader_argc)
87 SECURE_LOGD("loader argument %d : %s##", i, loader_argv[i]);
90 SignalManager::GetInst().UnblockSigchld();
92 _setup_stdio(basename(loader_argv[LOADER_ARG_PATH]));
94 if (execv(loader_argv[LOADER_ARG_PATH], loader_argv.data()) < 0) {
96 fprintf(stderr, "Failed to execute a file. path: %s, errno: %d:%s\n",
97 loader_argv[LOADER_ARG_PATH], errno,
98 strerror_r(errno, err_buf, sizeof(err_buf)));
103 void LoaderExecutor::OnRequestReceived(std::shared_ptr<AppPacket> app_packet) {
104 _W("Request received");
105 loader_argv_ = CreateArgsFromAppPacket(app_packet.get());
109 std::vector<std::string> LoaderExecutor::CreateLoaderArgv(
110 const LoaderContext* loader_context) {
111 std::string dummy(LOADER_ARG_LEN - 1, ' ');
112 std::vector<std::string> argv(LOADER_ARG_DUMMY + 1);
113 argv[LOADER_ARG_DUMMY] = std::move(dummy);
114 argv[LOADER_ARG_PATH] = loader_context->GetLoaderPath();
115 argv[LOADER_ARG_TYPE] = std::to_string(loader_context->GetType());
116 argv[LOADER_ARG_ID] = std::to_string(loader_context->GetLoaderId());
117 argv[LOADER_ARG_HYDRA] = loader_context->IsHydraMode() ? "1" : "0";
118 argv[LOADER_ARG_EXTRA] = loader_context->GetLoaderExtra();
122 } // namespace launchpad