2 * Copyright (c) 2000 - 2021 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 <bundle_internal.h>
23 #include <sys/types.h>
26 #include <bundle_cpp.h>
32 #include "app_request.h"
35 #include "include/aul_proc.h"
36 #include "include/aul_sock.h"
38 #include "aul/common/file_descriptor.hh"
41 using namespace aul::internal;
50 void SetName(std::string name) {
51 std::lock_guard<std::mutex> lock(mutex_);
52 name_ = std::move(name);
55 const std::string& GetName() {
56 std::lock_guard<std::mutex> lock(mutex_);
60 void SetExtra(tizen_base::Bundle extra) {
61 std::lock_guard<std::mutex> lock(mutex_);
62 extra_ = std::move(extra);
65 tizen_base::Bundle& GetExtra() {
66 std::lock_guard<std::mutex> lock(mutex_);
71 std::lock_guard<std::mutex> lock(mutex_);
76 std::lock_guard<std::mutex> lock(mutex_);
81 std::lock_guard<std::mutex> lock(mutex_);
82 return fd_.IsClosed();
88 tizen_base::Bundle extra_;
89 mutable std::mutex mutex_;
92 int ReadFromPath(const std::string& path, char* buf, size_t buf_size) {
93 int fd = open(path.c_str(), O_RDONLY);
95 _E("open() is failed. path(%s), errno(%d)", path.c_str(), errno);
99 FileDescriptor fd_closer(fd);
100 ssize_t bytes = read(fd, buf, buf_size - 1);
102 _E("read() is failed. errno(%d)", errno);
110 int SendAndReceive(int cmd, pid_t pid, uid_t uid, bundle** response) {
111 int fd = AppRequest(cmd, uid)
113 .SendSimply(AUL_SOCK_ASYNC);
114 if (fd < 0 || fd >= sysconf(_SC_OPEN_MAX)) {
115 _E("Failed to send request. error(%d)", fd);
119 FileDescriptor fd_closer(fd);
120 app_pkt_t* pkt = nullptr;
121 int ret = aul_sock_recv_reply_pkt(fd, &pkt);
123 _E("Failed to receive reply packet. error(%d)", ret);
127 std::unique_ptr<app_pkt_t, decltype(std::free)*> pkt_auto(pkt, std::free);
128 if (!(pkt->opt & AUL_SOCK_BUNDLE)) {
129 _E("Invalid protocol");
133 if (pkt->cmd != APP_GET_INFO_OK) {
134 _E("Failed to get name by pid(%d)", pid);
138 *response = bundle_decode(pkt->data, pkt->len);
139 if (*response == nullptr) {
140 _E("bundle_decode() is failed");
151 extern "C" API int aul_proc_get_uid(pid_t pid, uid_t* uid) {
152 if (pid < 1 || uid == nullptr) {
153 _E("Invalid parameter");
157 std::string path = "/proc/" + std::to_string(pid);
158 struct stat stat_buf;
159 int ret = stat(path.c_str(), &stat_buf);
161 _E("stat() is failed. path(%s), errno(%d)", path.c_str(), errno);
165 *uid = stat_buf.st_uid;
169 extern "C" API int aul_proc_get_attr(pid_t pid, char* buf, size_t buf_size) {
170 if (pid < 1 || buf == nullptr || buf_size <= 0) {
171 _E("Invalid parameter");
175 std::string path = "/proc/" + std::to_string(pid) + "/attr/current";
176 return ReadFromPath(path, buf, buf_size);
179 extern "C" API int aul_proc_get_cmdline(pid_t pid, char* buf, size_t buf_size) {
180 if (pid < 1 || buf == nullptr || buf_size <= 0) {
181 _E("Invalid parameter");
185 std::string path = "/proc/" + std::to_string(pid) + "/cmdline";
186 return ReadFromPath(path, buf, buf_size);
189 extern "C" API int aul_proc_register(const char* name, bundle* extra) {
190 if (name == nullptr || name[0] == '\0') {
191 _E("Invalid parameter");
195 if (!context.IsClosed()) {
196 _E("Already registered. Please call aul_proc_deregister() first");
200 tizen_base::Bundle b {{AUL_K_PROC_NAME, name}};
202 tizen_base::Bundle extra_data(extra, false, false);
203 auto raw = extra_data.ToRaw();
204 b.Add(AUL_K_PROC_EXTRA, reinterpret_cast<const char*>(raw.first.get()));
207 int ret = AppRequest(PROC_REGISTER, getuid())
209 .SendSimply(AUL_SOCK_ASYNC);
211 _E("Failed to send request. name(%s), error(%d)", name, ret);
215 int res = aul_sock_recv_result_with_fd(ret);
217 _E("Failed to receive the result. fd(%d)", res);
223 context.SetName(name);
225 context.SetExtra(tizen_base::Bundle(extra, true, true));
230 extern "C" API int aul_proc_deregister(void) {
231 if (context.IsClosed()) {
232 _E("Invalid context");
236 int ret = AppRequest(PROC_DEREGISTER, getuid())
237 .SendSimply(AUL_SOCK_NOREPLY);
239 _E("Failed to send request. error(%d)", ret);
247 extern "C" API int aul_proc_get_name(pid_t pid, char** name) {
248 if (pid < 1 || name == nullptr) {
249 _E("Invalid parameter");
253 if (pid == getpid() && !context.IsClosed() && !context.GetName().empty()) {
254 *name = strdup(context.GetName().c_str());
255 if (*name == nullptr) {
256 _E("strdup() is failed");
264 int ret = SendAndReceive(PROC_GET_NAME, pid, getuid(), &response);
268 tizen_base::Bundle b(response, false, true);
269 std::string val = b.GetString(AUL_K_PROC_NAME);
271 _E("Failed to get name");
275 *name = strdup(val.c_str());
276 if (*name == nullptr) {
277 _E("strdup() is failed");
284 extern "C" API int aul_proc_get_extra(pid_t pid, bundle** extra) {
285 if (pid < 1 || extra == nullptr) {
286 _E("Invalid parameter");
290 if (pid == getpid() && !context.IsClosed()) {
291 auto& extra_data = context.GetExtra();
292 *extra = bundle_dup(extra_data.GetHandle());
293 if (*extra == nullptr) {
294 _E("bundle_dup() is failed");
302 int ret = SendAndReceive(PROC_GET_EXTRA, pid, getuid(), &response);
306 tizen_base::Bundle b(response, false, true);
307 std::string raw = b.GetString(AUL_K_PROC_EXTRA);
309 _E("Failed to get extra");
313 tizen_base::Bundle extra_data(raw);
314 *extra = extra_data.Detach();