--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+#ifndef AUL_COMMON_FILE_DESCRIPTOR_HH_
+#define AUL_COMMON_FILE_DESCRIPTOR_HH_
+
+#include <unistd.h>
+#include <sys/types.h>
+
+namespace aul {
+
+class FileDescriptor {
+ public:
+ FileDescriptor(int fd = -1) : fd_(fd) {}
+
+ virtual ~FileDescriptor() {
+ if (fd_ > -1)
+ close(fd_);
+ }
+
+ void Set(int fd) {
+ fd_ = fd;
+ }
+
+ int Get() const {
+ return fd_;
+ }
+
+ void Close() {
+ if (fd_ > -1) {
+ close(fd_);
+ fd_ = -1;
+ }
+ }
+
+ bool IsClosed() {
+ return fd_ < 0 ? true : false;
+ }
+
+ private:
+ int fd_;
+};
+
+} // namespace aul
+
+#endif // AUL_COMMON_FILE_DESCRIPTOR_HH_
APP_GET_APP_CONTROL_DEFAULT_APP = 159,
APP_LIFECYCLE_GET_STATE = 160,
+ PROC_REGISTER = 161,
+ PROC_DEREGISTER = 162,
+ PROC_GET_NAME = 163,
+ PROC_GET_EXTRA = 164,
+
APP_CMD_MAX
};
* @since_tizen 6.5
*/
#define AUL_K_MOUNT_ALLOWED_RES_DIR "__AUL_MOUNT_ALLOWED_RES_DIR__"
+
+/**
+ * @brief Definition for AUL: The name of the process.
+ * @since_tizen 6.5
+ */
+#define AUL_K_PROC_NAME "__AUL_PROC_NAME__"
+
+/**
+ * @brief Definition for AUL: The extra data of the process.
+ * @since_tizen 6.5
+ */
+#define AUL_K_PROC_EXTRA "__AUL_PROC_EXTRA__"
/*
- * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2000 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
*
- * Licensed under the Apache License, Version 2.0 (the License);
+ * 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,
+ * 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.
*/
-#pragma once
+#ifndef __AUL_PROC_H__
+#define __AUL_RPOC_H__
+#include <sys/types.h>
#include <unistd.h>
-#include <ctype.h>
+
+#include <aul.h>
+#include <bundle.h>
#ifdef __cplusplus
extern "C" {
#endif
-/*
- * This API is only for Appfw internally.
+/**
+ * @brief Gets the user ID of the process from the proc filesystem.
+ * @since_tizen 6.5
+ * @param[in] pid The process ID
+ * @param[out] uid The user ID
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @remarks This function is only for App Framework internally.
+ */
+int aul_proc_get_uid(pid_t pid, uid_t *uid);
+
+/**
+ * @brief Gets the SMACK label of the process from the proc filesystem.
+ * @since_tizen 6.5
+ * @param[in] pid The process ID
+ * @param[in] buf The buffer
+ * @param[in] buf_size The size of the buffer
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @remarks This function is only for App Framework internally.
+ */
+int aul_proc_get_attr(pid_t pid, char *buf, size_t buf_size);
+
+/**
+ * @brief Gets the cmdline of the process from the proc filesystem.
+ * @since_tizen 6.5
+ * @param[in] pid The process ID
+ * @param[in] buf The buffer
+ * @param[in] buf_size The size of the buffer
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @remarks This function is only for App Framework internally.
+ */
+int aul_proc_get_cmdline(pid_t pid, char *buf, size_t buf_size);
+
+/**
+ * @brief Registers the process information,
+ * @details This function registers the process information to the application manager daemon.
+ * After calling this function, the other process can get the process information
+ * using aul_proc_get_name() or aul_proc_get_extra().
+ * @since_tizen 6.5
+ * @param[in] name The process name
+ * @param[in] extra The extra data
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @remarks This function is only for App Framework internally.
*/
-uid_t aul_proc_get_usr_bypid(int pid);
+int aul_proc_register(const char *name, bundle *extra);
+
+/**
+ * @brief Deregister the process information.
+ * @since_tizen 6.5
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @remarks This function is only for App Framework internally.
+ */
+int aul_proc_deregister(void);
+
+/**
+ * @brief Gets the process name.
+ * @since_tizen 6.5
+ * @remarks The @a name MUST be released using free().
+ * @param[in] pid The process ID
+ * @param[out] name The process name
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @remarks This function is only for App Framework internally.
+ */
+int aul_proc_get_name(pid_t pid, char **name);
+
+/**
+ * @brief Gets the extra data of the process.
+ * @since_tizen 6.5
+ * @reamrks The @a extra MUST be released using bundle_free().
+ * @param[in] pid The process ID
+ * @param[out] extra The extra data
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @remarks This function is only for App Framework internally.
+ */
+int aul_proc_get_extra(pid_t pid, bundle **extra);
#ifdef __cplusplus
}
#endif
+
+#endif /* __AUL_PROC_H__ */
"APP_GET_APP_CONTROL_DEFAULT_APP",
"APP_LIFECYCLE_GET_STATE",
+ "PROC_REGISTER",
+ "PROC_DEREGISTER",
+ "PROC_GET_NAME",
+ "PROC_GET_EXTRA",
+
"CUSTOM_COMMAND"
};
+++ /dev/null
-/*
- * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * 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.
- */
-
-#define _GNU_SOURCE
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "aul_api.h"
-#include "aul_proc.h"
-#include "aul_util.h"
-
-#define MAX_CMD_BUFSZ 1024
-
-API uid_t aul_proc_get_usr_bypid(int pid)
-{
- char buf[MAX_CMD_BUFSZ];
- int ret;
- uid_t uid;
- struct stat DirStat;
-
- snprintf(buf, sizeof(buf), "/proc/%d", pid);
- ret = stat(buf, &DirStat);
- if (ret < 0)
- uid = (uid_t)-1;
- else
- uid = DirStat.st_uid;
-
- return uid;
-}
-
--- /dev/null
+/*
+ * Copyright (c) 2000 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+#include <bundle_internal.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <bundle_cpp.h>
+
+#include <string>
+#include <memory>
+#include <mutex>
+
+#include "app_request.h"
+#include "aul_api.h"
+#include "aul_util.h"
+#include "include/aul_proc.h"
+#include "include/aul_sock.h"
+
+#include "aul/common/file_descriptor.hh"
+
+using namespace aul;
+using namespace aul::internal;
+
+namespace {
+
+class ProcContext {
+ public:
+ ProcContext() {}
+ ~ProcContext() {}
+
+ void SetName(std::string name) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ name_ = std::move(name);
+ }
+
+ const std::string& GetName() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return name_;
+ }
+
+ void SetExtra(tizen_base::Bundle extra) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ extra_ = std::move(extra);
+ }
+
+ tizen_base::Bundle& GetExtra() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return extra_;
+ }
+
+ void SetFd(int fd) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ fd_.Set(fd);
+ }
+
+ void Close() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ fd_.Close();
+ }
+
+ bool IsClosed() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return fd_.IsClosed();
+ }
+
+ private:
+ FileDescriptor fd_;
+ std::string name_;
+ tizen_base::Bundle extra_;
+ mutable std::mutex mutex_;
+};
+
+int ReadFromPath(const std::string& path, char* buf, size_t buf_size) {
+ int fd = open(path.c_str(), O_RDONLY);
+ if (fd < 0) {
+ _E("open() is failed. path(%s), errno(%d)", path.c_str(), errno);
+ return AUL_R_ERROR;
+ }
+
+ FileDescriptor fd_closer(fd);
+ ssize_t bytes = read(fd, buf, buf_size - 1);
+ if (bytes <= 0) {
+ _E("read() is failed. errno(%d)", errno);
+ return AUL_R_ERROR;
+ }
+
+ buf[bytes] = '\0';
+ return AUL_R_OK;
+}
+
+int SendAndReceive(int cmd, pid_t pid, uid_t uid, bundle** response) {
+ int fd = AppRequest(cmd, uid)
+ .SetPid(pid)
+ .SendSimply(AUL_SOCK_ASYNC);
+ if (fd < 0 || sysconf(_SC_OPEN_MAX)) {
+ _E("Failed to send request. error(%d)", fd);
+ return fd;
+ }
+
+ FileDescriptor fd_closer(fd);
+ app_pkt_t* pkt = nullptr;
+ int ret = aul_sock_recv_reply_pkt(fd, &pkt);
+ if (ret < 0) {
+ _E("Failed to receive reply packet. error(%d)", ret);
+ return AUL_R_ECOMM;
+ }
+
+ std::unique_ptr<app_pkt_t, decltype(std::free)*> pkt_auto(pkt, std::free);
+ if (!(pkt->opt & AUL_SOCK_BUNDLE)) {
+ _E("Invalid protocol");
+ return AUL_R_ECOMM;
+ }
+
+ if (pkt->cmd != APP_GET_INFO_OK) {
+ _E("Failed to get name by pid(%d)", pid);
+ return AUL_R_ERROR;
+ }
+
+ *response = bundle_decode(pkt->data, pkt->len);
+ if (*response == nullptr) {
+ _E("bundle_decode() is failed");
+ return AUL_R_ERROR;
+ }
+
+ return AUL_R_OK;
+}
+
+ProcContext context;
+
+} // namespace
+
+extern "C" API int aul_proc_get_uid(pid_t pid, uid_t* uid) {
+ if (pid < 1 || uid == nullptr) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ std::string path = "/proc/" + std::to_string(pid);
+ struct stat stat_buf;
+ int ret = stat(path.c_str(), &stat_buf);
+ if (ret < 0) {
+ _E("stat() is failed. path(%s), errno(%d)", path.c_str(), errno);
+ return AUL_R_ERROR;
+ }
+
+ *uid = stat_buf.st_uid;
+ return AUL_R_OK;
+}
+
+extern "C" API int aul_proc_get_attr(pid_t pid, char* buf, size_t buf_size) {
+ if (pid < 1 || buf == nullptr || buf_size <= 0) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ std::string path = "/proc/" + std::to_string(pid) + "/attr/current";
+ return ReadFromPath(path, buf, buf_size);
+}
+
+extern "C" API int aul_proc_get_cmdline(pid_t pid, char* buf, size_t buf_size) {
+ if (pid < 1 || buf == nullptr || buf_size <= 0) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ std::string path = "/proc/" + std::to_string(pid) + "/cmdline";
+ return ReadFromPath(path, buf, buf_size);
+}
+
+extern "C" API int aul_proc_register(const char* name, bundle* extra) {
+ if (name == nullptr || name[0] == '\0') {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ if (!context.IsClosed()) {
+ _E("Already registered. Please call aul_proc_unset_name() first");
+ return AUL_R_ERROR;
+ }
+
+ tizen_base::Bundle b {{AUL_K_PROC_NAME, name}};
+ if (extra) {
+ tizen_base::Bundle extra_data(extra, false, false);
+ auto raw = extra_data.ToRaw();
+ b.Add(AUL_K_PROC_EXTRA, reinterpret_cast<const char*>(raw.first.get()));
+ }
+
+ int ret = AppRequest(PROC_REGISTER, getuid())
+ .With(b)
+ .SendSimply(AUL_SOCK_ASYNC);
+ if (ret < 0) {
+ _E("Failed to send request. name(%s), error(%d)", name, ret);
+ return ret;
+ }
+
+ context.SetFd(ret);
+ context.SetName(name);
+ if (extra)
+ context.SetExtra(tizen_base::Bundle(extra, true, true));
+
+ return AUL_R_OK;
+}
+
+extern "C" API int aul_proc_deregister(void) {
+ if (context.IsClosed()) {
+ _E("Invalid context");
+ return AUL_R_ERROR;
+ }
+
+ int ret = AppRequest(PROC_DEREGISTER, getuid())
+ .SendSimply(AUL_SOCK_NOREPLY);
+ if (ret < 0) {
+ _E("Failed to send request. error(%d)", ret);
+ return ret;
+ }
+
+ context.Close();
+ return AUL_R_OK;
+}
+
+extern "C" API int aul_proc_get_name(pid_t pid, char** name) {
+ if (pid < 1 || name == nullptr) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ if (pid == getpid() && !context.IsClosed() && !context.GetName().empty()) {
+ *name = strdup(context.GetName().c_str());
+ if (*name == nullptr) {
+ _E("strdup() is failed");
+ return AUL_R_ENOMEM;
+ }
+
+ return AUL_R_OK;
+ }
+
+ bundle* response;
+ int ret = SendAndReceive(PROC_GET_NAME, pid, getuid(), &response);
+ if (ret != AUL_R_OK)
+ return ret;
+
+ tizen_base::Bundle b(response, false, true);
+ std::string val = b.GetString(AUL_K_PROC_NAME);
+ if (val.empty()) {
+ _E("Failed to get name");
+ return AUL_R_ERROR;
+ }
+
+ *name = strdup(val.c_str());
+ if (*name == nullptr) {
+ _E("strdup() is failed");
+ return AUL_R_ENOMEM;
+ }
+
+ return AUL_R_OK;
+}
+
+extern "C" API int aul_proc_get_extra(pid_t pid, bundle** extra) {
+ if (pid < 1 || extra == nullptr) {
+ _E("Invalid parameter");
+ return AUL_R_EINVAL;
+ }
+
+ if (pid == getpid() && !context.IsClosed()) {
+ auto& extra_data = context.GetExtra();
+ *extra = bundle_dup(extra_data.GetHandle());
+ if (*extra == nullptr) {
+ _E("bundle_dup() is failed");
+ return AUL_R_ENOMEM;
+ }
+
+ return AUL_R_OK;
+ }
+
+ bundle* response;
+ int ret = SendAndReceive(PROC_GET_EXTRA, pid, getuid(), &response);
+ if (ret != AUL_R_OK)
+ return ret;
+
+ tizen_base::Bundle b(response, false, true);
+ std::string raw = b.GetString(AUL_K_PROC_EXTRA);
+ if (raw.empty()) {
+ _E("Failed to get extra");
+ return AUL_R_ERROR;
+ }
+
+ tizen_base::Bundle extra_data(raw);
+ *extra = extra_data.Detach();
+ return AUL_R_OK;
+}
#include "aul.h"
#include "aul/api/aul_app_lifecycle.h"
#include "aul_svc.h"
+#include "aul_proc.h"
#include "menu_db_util.h"
#define MAX_LOCAL_BUFSZ 128
return ret;
}
+static void __foreach_extra_cb(const char *key, const int type, const bundle_keyval_t *kb,
+ void *user_data)
+{
+ printf("key: %s, type:%d\n", key, type);
+}
+
+static int register_proc_test(void)
+{
+ char *name = NULL;
+ bundle *extra = NULL;
+ int ret;
+
+ if (gargc > 3)
+ extra = create_internal_bundle(3);
+
+ printf("[aul_proc_register] %s\n", gargv[2]);
+ ret = aul_proc_register(gargv[2], extra);
+ if (extra)
+ bundle_free(extra);
+ printf("result: %d\n", ret);
+ if (ret != AUL_R_OK)
+ return ret;
+
+ printf("[aul_proc_get_name] %d\n", getpid());
+ ret = aul_proc_get_name(getpid(), &name);
+ printf("result: %d, name: %s\n", ret, name);
+ free(name);
+
+ extra = NULL;
+ printf("[aul_proc_get_extra] %d\n", getpid());
+ ret = aul_proc_get_extra(getpid(), &extra);
+ printf("result:%d\n", ret);
+ if (extra) {
+ bundle_foreach(extra, __foreach_extra_cb, NULL);
+ bundle_free(extra);
+ }
+
+ return ret;
+}
+
+static int get_proc_name_test(void)
+{
+ char *name = NULL;
+ int ret;
+
+ printf("[aul_proc_get_name] %s\n", gargv[2]);
+ ret = aul_proc_get_name(atoi(gargv[2]), &name);
+ printf("result: %d, name: %s\n", ret, name);
+ free(name);
+ return ret;
+}
+
+static int get_proc_extra_test(void)
+{
+ bundle* extra = NULL;
+ int ret;
+
+ printf("[aul_proc_get_extra] %s\n", gargv[2]);
+ ret = aul_proc_get_extra(atoi(gargv[2]), &extra);
+ printf("result: %d\n", ret);
+ if (extra) {
+ bundle_foreach(extra, __foreach_extra_cb, NULL);
+ bundle_free(extra);
+ }
+
+ return ret;
+}
+
static int test_regex()
{
char *token;
"[usage] get_default_appid <operation> <uri> <mime>"},
{"get_app_lifecycle", get_app_lifecycle_test, "aul_app_lifecycle_get_state",
"[usage] get_app_lifecycle <appid>"},
+ {"register_proc", register_proc_test, "aul_proc_register",
+ "[usage] register_proc <name> <key> <value> <key> <value> ..."},
+ {"get_proc_name", get_proc_name_test, "aul_proc_get_name",
+ "[usage] get_proc_name <pid>"},
+ {"get_proc_extra", get_proc_extra_test, "aul_proc_get_extra",
+ "[usage] get_proc_extra <pid>"},
};
int callfunc(char *testname)