2 * Copyright (c) 2015 - 2016 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.
20 #include <sys/types.h>
22 #include <sys/mount.h>
27 #include <sys/xattr.h>
29 #include <sys/socket.h>
31 #include <linux/limits.h>
33 #include <sys/capability.h>
34 #include <tzplatform_config.h>
37 #include <systemd/sd-journal.h>
39 #include <sys/resource.h>
40 #include <sys/personality.h>
41 #include <sys/prctl.h>
42 #include <dbus/dbus.h>
45 #include "launchpad_common.h"
46 #include "launchpad_types.h"
49 #define MAX_PATH_LEN 1024
50 #define MAX_CMD_BUFSZ 1024
52 #define MAX_PENDING_CONNECTIONS 10
53 #define AUL_PKT_HEADER_SIZE (sizeof(int) + sizeof(int) + sizeof(int))
54 #define PATH_AMD_SOCK "/run/aul/daemons/.amd-sock"
55 #define PATH_DEV_NULL "/dev/null"
56 #define MAX_TEP_IS_MOUNT_RETRY_CNT 100
57 #define MAX_PAYLOAD_SIZE (1024 * 1024 * 1)
59 #define TEP_BUS_NAME "org.tizen.system.deviced"
60 #define TEP_OBJECT_PATH "/Org/Tizen/System/DeviceD/Tzip"
61 #define TEP_INTERFACE_NAME "org.tizen.system.deviced.Tzip"
62 #define TEP_IS_MOUNTED_METHOD "IsMounted"
64 #define APP2SD_BUS_NAME "org.tizen.app2sd"
65 #define APP2SD_OBJECT_PATH "/org/tizen/app2sd"
66 #define APP2SD_INTERFACE_NAME "org.tizen.app2sd"
67 #define APP2SD_ONDEMANDSETUPINIT_METHOD "OndemandSetupInit"
68 #define APP2SD_RETRY_MAX 5
69 #define APP2SD_WAIT_USEC (1000000 / 2) /* 0.5 sec */
71 #ifndef PR_TASK_PERF_USER_TRACE
72 #define PR_TASK_PERF_USER_TRACE 666
75 void _get_cpu_idle(unsigned long long *total, unsigned long long *idle)
79 unsigned long long sum = 0;
80 unsigned long long val;
81 unsigned long long iv = 0;
84 fp = fopen("/proc/stat", "rt");
89 if (fscanf(fp, "%3s", buf) == -1) {
94 for (i = 0; i < 10; i++) {
95 if (fscanf(fp, "%lld", &val) == -1) {
100 if (sum + val < sum) {
107 if (i == 3) /* idle */
117 int _set_sock_option(int fd, int cli)
119 struct timeval tv = { 5, 200 * 1000 }; /* 5.2 sec */
124 size = AUL_SOCK_MAXBUFF;
125 ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
127 _E("Failed to set SO_SNDBUF option on socket. errno(%d)",
132 ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
134 _E("Failed to set SO_RCVBUF option on socket. errno(%d)",
140 ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
142 _E("Failed to set SO_RCVTIMEO option on socket. " \
147 flag = fcntl(fd, F_GETFD);
149 ret = fcntl(fd, F_SETFD, flag);
151 _E("Failed to manipulate fd(F_SETFD), errno(%d)",
160 static int __parse_app_path(const char *arg, char *out, int out_size)
164 char *start_out = out;
166 if (arg == NULL || out == NULL) {
167 /* Handles null buffer*/
171 for (i = 0; out_size > 1; i++) {
195 case 2: /* escape start*/
210 case 4: /* character escape*/
211 if (arg[i] == '\0') {
221 if (out != start_out) {
230 return -1; /* error*/
231 case 7: /* terminate*/
248 static int __create_client_socket(const char *path)
250 struct sockaddr_un addr = { 0, };
251 int retry = CONNECT_RETRY_COUNT;
254 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
256 _E("Failed to create socket(%s). errno(%d)", path, errno);
260 addr.sun_family = AF_UNIX;
261 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);
262 while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
263 if (errno != ETIMEDOUT || retry <= 0) {
264 _E("Failed to connect socket(%s). errno(%d)",
270 usleep(CONNECT_RETRY_TIME);
272 _W("Retry(%d) to connect %s", retry, path);
278 int _send_cmd_to_amd(int cmd)
280 app_pkt_t pkt = {0,};
284 fd = __create_client_socket(PATH_AMD_SOCK);
289 ret = send(fd, &pkt, sizeof(app_pkt_t), MSG_NOSIGNAL);
291 _E("Failed to send cmd(%d), errno(%d)", cmd, errno);
300 int _create_server_sock(const char *name)
302 struct sockaddr_un saddr;
305 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
306 /* support above version 2.6.27*/
308 if (errno == EINVAL) {
309 fd = socket(AF_UNIX, SOCK_STREAM, 0);
311 _E("second chance - socket create error");
320 memset(&saddr, 0, sizeof(saddr));
321 saddr.sun_family = AF_UNIX;
323 snprintf(saddr.sun_path, sizeof(saddr.sun_path),
325 SOCKET_PATH, getuid(), name);
326 unlink(saddr.sun_path);
328 if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
334 if (_set_sock_option(fd, 0) < 0) {
335 _E("Failed to set sock option");
340 if (listen(fd, 128) == -1) {
349 app_pkt_t *_recv_pkt_raw(int fd)
353 unsigned char buf[AUL_SOCK_MAXBUFF];
360 /* receive header(cmd, datalen) */
361 len = recv(fd, buf, AUL_PKT_HEADER_SIZE, 0);
366 if (len < AUL_PKT_HEADER_SIZE) {
370 memcpy(&cmd, buf, sizeof(int));
371 memcpy(&datalen, buf + sizeof(int), sizeof(int));
372 memcpy(&opt, buf + sizeof(int) + sizeof(int), sizeof(int));
374 if (datalen < 0 || datalen > MAX_PAYLOAD_SIZE) {
375 _E("Invalid protocol. datalen(%d)", datalen);
379 /* allocate for a null byte */
380 pkt = (app_pkt_t *)calloc(1, AUL_PKT_HEADER_SIZE + datalen + 1);
382 _E("failed to alloc app_pkt_t");
390 while (len != pkt->len) {
391 ret = recv(fd, pkt->data + len, pkt->len - len, 0);
393 _E("recv error %d %d", len, pkt->len);
398 _D("recv len %d %d", len, pkt->len);
404 app_pkt_t *_accept_recv_pkt_raw(int fd, int *clifd, struct ucred *cr)
406 struct sockaddr_un aul_addr = { 0, };
410 int cl = sizeof(struct ucred);
412 sun_size = sizeof(struct sockaddr_un);
414 newfd = accept(fd, (struct sockaddr *)&aul_addr,
415 (socklen_t *) &sun_size);
422 if (getsockopt(newfd, SOL_SOCKET, SO_PEERCRED, cr,
423 (socklen_t *) &cl) < 0) {
424 _E("peer information error");
429 if (_set_sock_option(newfd, 1) < 0) {
430 _E("Failed to set sock option");
435 pkt = _recv_pkt_raw(newfd);
437 _E("failed to receive pkt from client");
446 int _send_pkt_raw(int client_fd, app_pkt_t *pkt)
452 if (client_fd == -1 || pkt == NULL) {
453 _E("arguments error!");
457 pkt_size = AUL_PKT_HEADER_SIZE + pkt->len;
459 while (sent != pkt_size) {
460 send_ret = send(client_fd, (char *)pkt + sent,
461 pkt_size - sent, MSG_NOSIGNAL);
462 if (send_ret == -1) {
463 _E("send error! (%d)", errno);
468 _D("send(%d: ret: %d) : %d / %d",
469 client_fd, send_ret, sent, pkt_size);
475 appinfo_t *_appinfo_create(bundle *kb)
477 appinfo_t *menu_info;
478 const char *ptr = NULL;
480 menu_info = calloc(1, sizeof(appinfo_t));
481 if (menu_info == NULL)
484 ptr = bundle_get_val(kb, AUL_K_APPID);
486 menu_info->appid = strdup(ptr);
487 ptr = bundle_get_val(kb, AUL_K_EXEC);
489 menu_info->app_path = strdup(ptr);
490 if (menu_info->app_path != NULL)
491 menu_info->original_app_path = strdup(menu_info->app_path);
492 ptr = bundle_get_val(kb, AUL_K_PACKAGETYPE);
494 menu_info->pkg_type = strdup(ptr);
495 ptr = bundle_get_val(kb, AUL_K_APP_TYPE);
497 menu_info->app_type = strdup(ptr);
498 ptr = bundle_get_val(kb, AUL_K_HWACC);
500 menu_info->hwacc = strdup(ptr);
501 ptr = bundle_get_val(kb, AUL_K_TASKMANAGE);
503 menu_info->taskmanage = strdup(ptr);
504 ptr = bundle_get_val(kb, AUL_K_PKGID);
506 menu_info->pkgid = strdup(ptr);
507 ptr = bundle_get_val(kb, AUL_K_COMP_TYPE);
509 menu_info->comp_type = strdup(ptr);
510 ptr = bundle_get_val(kb, AUL_K_INTERNAL_POOL);
512 menu_info->internal_pool = strdup(ptr);
513 ptr = bundle_get_val(kb, AUL_K_ROOT_PATH);
515 menu_info->root_path = strdup(ptr);
517 ptr = bundle_get_val(kb, AUL_K_LOADER_NAME);
519 menu_info->loader_name = strdup(ptr);
521 ptr = bundle_get_val(kb, AUL_K_IS_GLOBAL);
522 if (ptr && strcmp(ptr, "true") == 0)
523 menu_info->global = true;
525 menu_info->global = false;
527 if (!_appinfo_get_app_path(menu_info)) {
528 _appinfo_free(menu_info);
535 char *_appinfo_get_app_path(appinfo_t *menu_info)
541 if (!menu_info || menu_info->app_path == NULL)
544 while (menu_info->app_path[i] != 0) {
545 if (menu_info->app_path[i] == ' '
546 || menu_info->app_path[i] == '\t') {
554 free(menu_info->app_path);
555 menu_info->app_path = NULL;
556 } else if (path_len > 0) {
557 tmp_app_path = malloc(sizeof(char) * (path_len + 1));
558 if (tmp_app_path == NULL)
560 snprintf(tmp_app_path, path_len + 1, "%s", menu_info->app_path);
561 free(menu_info->app_path);
562 menu_info->app_path = tmp_app_path;
565 return menu_info->app_path;
568 void _appinfo_free(appinfo_t *menu_info)
570 if (menu_info == NULL)
573 if (menu_info->appid != NULL)
574 free(menu_info->appid);
575 if (menu_info->app_path != NULL)
576 free(menu_info->app_path);
577 if (menu_info->original_app_path != NULL)
578 free(menu_info->original_app_path);
579 if (menu_info->pkg_type != NULL)
580 free(menu_info->pkg_type);
581 if (menu_info->app_type != NULL)
582 free(menu_info->app_type);
583 if (menu_info->hwacc != NULL)
584 free(menu_info->hwacc);
585 if (menu_info->taskmanage != NULL)
586 free(menu_info->taskmanage);
587 if (menu_info->pkgid != NULL)
588 free(menu_info->pkgid);
589 if (menu_info->comp_type != NULL)
590 free(menu_info->comp_type);
591 if (menu_info->internal_pool != NULL)
592 free(menu_info->internal_pool);
593 if (menu_info->root_path != NULL)
594 free(menu_info->root_path);
595 if (menu_info->loader_name != NULL)
596 free(menu_info->loader_name);
601 static bool __validate_bundle_key(const char *key)
606 if (!strncmp(key, "__AUL_", strlen("__AUL_")))
609 if (!strncmp(key, "__APP_SVC_", strlen("__APP_SVC_")))
615 void _modify_bundle(bundle *kb, int caller_pid, appinfo_t *menu_info, int cmd)
618 char exe[MAX_PATH_LEN];
623 bundle_del(kb, AUL_K_APPID);
624 bundle_del(kb, AUL_K_EXEC);
625 bundle_del(kb, AUL_K_APP_TYPE);
626 bundle_del(kb, AUL_K_PACKAGETYPE);
627 bundle_del(kb, AUL_K_TASKMANAGE);
628 bundle_del(kb, AUL_K_PKGID);
629 bundle_del(kb, AUL_K_COMP_TYPE);
631 /* Parse app_path to retrieve default bundle*/
632 if (cmd == PAD_CMD_LAUNCH) {
633 ptr = menu_info->original_app_path;
634 flag = __parse_app_path(ptr, exe, sizeof(exe));
637 SECURE_LOGD("parsing app_path: EXEC - %s", exe);
640 flag = __parse_app_path(ptr, key, sizeof(key));
645 flag = __parse_app_path(ptr, value,
651 /*bundle_del(kb, key);*/
652 if (__validate_bundle_key(key))
653 bundle_add(kb, key, value);
655 } else if (flag == 0)
656 _D("parsing app_path: No arguments");
658 _D("parsing app_path: Invalid argument");
662 int _connect_to_launchpad(int type, int id)
669 _D("[launchpad] enter, type: %d", type);
671 snprintf(path, sizeof(path), "%s/daemons/%d/%s%d-%d",
672 SOCKET_PATH, getuid(), LAUNCHPAD_LOADER_SOCKET_NAME,
674 fd = __create_client_socket(path);
678 client_pid = getpid();
679 send_ret = send(fd, &client_pid, sizeof(client_pid), MSG_NOSIGNAL);
680 _D("send(%d) : %d", client_pid, send_ret);
681 if (send_ret == -1) {
682 _E("send error(%d)", errno);
687 SECURE_LOGD("[launchpad] done, connect fd: %d", fd);
691 #ifdef TIZEN_FEATURE_SET_PERSONALITY_32
692 static void __set_execution_domain(void)
697 res = personality(PER_LINUX32);
699 _E("personality() failed, error: %d (%s)",
701 strerror_r(errno, err_buf, sizeof(err_buf)));
704 #endif /* TIZEN_FEATURE_SET_PERSONALITY_32 */
706 static void __set_lang_env(void)
710 lang = getenv("LANG");
712 lang = "en_US.UTF-8";
713 setenv("LANG", lang, 1);
716 setenv("LANGUAGE", lang, 1);
717 setenv("LC_MESSAGES", lang, 1);
718 setenv("LC_ALL", lang, 1);
721 static void __set_region_env(void)
725 region = getenv("LC_CTYPE");
727 region = "en_US.UTF-8";
728 setenv("LC_CTYPE", region, 1);
731 setenv("LC_NUMERIC", region, 1);
732 setenv("LC_TIME", region, 1);
733 setenv("LC_COLLATE", region, 1);
734 setenv("LC_MONETARY", region, 1);
735 setenv("LC_PAPER", region, 1);
736 setenv("LC_NAME", region, 1);
737 setenv("LC_ADDRESS", region, 1);
738 setenv("LC_TELEPHONE", region, 1);
739 setenv("LC_MEASUREMENT", region, 1);
740 setenv("LC_IDENTIFICATION", region, 1);
743 void _set_env(appinfo_t *menu_info, bundle *kb)
746 char buf[MAX_LOCAL_BUFSZ];
748 str = bundle_get_val(kb, AUL_K_STARTTIME);
750 setenv("APP_START_TIME", str, 1);
752 if (menu_info->hwacc != NULL)
753 setenv("HWACC", menu_info->hwacc, 1);
754 if (menu_info->taskmanage != NULL)
755 setenv("TASKMANAGE", menu_info->taskmanage, 1);
756 if (menu_info->root_path != NULL)
757 setenv("AUL_ROOT_PATH", menu_info->root_path, 1);
758 if (menu_info->appid != NULL)
759 setenv("AUL_APPID", menu_info->appid, 1);
760 if (menu_info->pkgid != NULL)
761 setenv("AUL_PKGID", menu_info->pkgid, 1);
762 if (menu_info->app_type != NULL)
763 setenv("RUNTIME_TYPE", menu_info->app_type, 1);
765 str = bundle_get_val(kb, AUL_K_WAYLAND_DISPLAY);
767 setenv("WAYLAND_DISPLAY", str, 1);
769 str = bundle_get_val(kb, AUL_K_WAYLAND_WORKING_DIR);
771 setenv("XDG_RUNTIME_DIR", str, 1);
773 str = bundle_get_val(kb, AUL_K_API_VERSION);
775 setenv("TIZEN_API_VERSION", str, 1);
777 snprintf(buf, sizeof(buf), "%d", getpid());
778 setenv("AUL_PID", buf, 1);
782 #ifdef TIZEN_FEATURE_SET_PERSONALITY_32
783 __set_execution_domain();
784 #endif /* TIZEN_FEATURE_SET_PERSONALITY_32 */
787 char **_create_argc_argv(bundle *kb, int *margc)
792 argc = bundle_export_to_argv(kb, &argv);
798 char *_get_libdir(const char *path)
806 path_dup = strdup(path);
807 if (path_dup == NULL)
809 ptr = strrchr(path_dup, '/');
817 snprintf(buf, sizeof(buf), "%s/../lib/", path_dup);
820 if (access(buf, F_OK) == -1)
826 static int __delete_dir(const char *path)
829 struct dirent *dentry = NULL;
841 while ((dentry = readdir(dp)) != NULL) {
842 if (!strcmp(dentry->d_name, ".") || !strcmp(dentry->d_name, ".."))
845 snprintf(buf, sizeof(buf), "%s/%s", path, dentry->d_name);
846 ret = stat(buf, &statbuf);
848 if (S_ISDIR(statbuf.st_mode))
861 int _delete_sock_path(int pid, uid_t uid)
866 snprintf(path, sizeof(path), "/run/aul/apps/%d/%d", uid, pid);
867 r = access(path, F_OK);
870 _E("Failed to access %s. errno(%d)", path, errno);
875 if (access(path, F_OK) == 0) {
876 _E("Failed to delete %s", path);
883 int _close_all_fds(void)
886 struct dirent *dentry = NULL;
890 const char *aul_listen_fd;
892 aul_listen_fd = getenv("AUL_LISTEN_FD");
894 aul_fd = atoi(aul_listen_fd);
896 dp = opendir("/proc/self/fd");
899 max_fd = sysconf(_SC_OPEN_MAX);
900 for (fd = 3; fd < max_fd; fd++) {
908 while ((dentry = readdir(dp)) != NULL) {
909 if (!isdigit(dentry->d_name[0]))
912 fd = atoi(dentry->d_name);
916 if (fd == dirfd(dp) || fd == aul_fd)
926 static int __redirect_stdin(void)
931 fd = open(PATH_DEV_NULL, O_RDONLY | O_NOCTTY);
934 _E("open(%s) is failed. errno(%d)", PATH_DEV_NULL, errno);
938 ret = dup2(fd, STDIN_FILENO);
940 _W("dup2(%d, 0) is failed. errno(%d)", fd, errno);
946 static int __redirect_stdout(const char *ident)
951 fd = sd_journal_stream_fd(ident, LOG_INFO, 0);
954 _W("sd_journal_stream_fd() is failed. error(%d)", fd);
955 fd = open(PATH_DEV_NULL, O_WRONLY | O_NOCTTY);
958 _E("open(%s) is failed. errno(%d)",
959 PATH_DEV_NULL, errno);
960 close(STDOUT_FILENO);
965 ret = dup2(fd, STDOUT_FILENO);
968 _E("dup(%d, 1) is failed. errno(%d)", fd, errno);
969 close(STDOUT_FILENO);
976 static int __redirect_stderr(const char *ident)
981 fd = sd_journal_stream_fd(ident, LOG_WARNING, 0);
984 _W("sd_journal_stream_fd() is failed. error(%d)", fd);
985 fd = open(PATH_DEV_NULL, O_WRONLY | O_NOCTTY);
988 _E("open(%s) is failed. errno(%d)",
989 PATH_DEV_NULL, errno);
990 close(STDERR_FILENO);
995 ret = dup2(fd, STDERR_FILENO);
998 _E("dup(%d, 2) is failed. errno(%d)", fd, errno);
999 close(STDERR_FILENO);
1007 int _setup_stdio(const char *ident)
1011 ret = __redirect_stdin();
1015 ret = __redirect_stdout(ident);
1019 ret = __redirect_stderr(ident);
1026 int _set_priority(int prio)
1030 r = setpriority(PRIO_PGRP, 0, prio);
1032 SECURE_LOGE("Failed to set process(%d) priority(%d) - err(%d)",
1033 getpid(), prio, errno);
1039 static int __dbus_send_message(DBusMessage *callback(void *), void *user_data,
1040 int timeout, int *result)
1043 DBusConnection *conn;
1044 DBusMessage *msg = NULL;
1045 DBusMessageIter args;
1046 DBusPendingCall *pending = NULL;
1051 dbus_error_init(&err);
1052 conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
1054 _E("Failed to connect to D-Bus Daemon");
1059 msg = callback(user_data);
1061 _E("Message is nullptr");
1065 r = dbus_connection_send_with_reply(conn, msg, &pending, timeout);
1066 if (!r || !pending) {
1067 _E("Failed to send message");
1072 dbus_connection_flush(conn);
1073 dbus_message_unref(msg);
1075 dbus_pending_call_block(pending);
1076 msg = dbus_pending_call_steal_reply(pending);
1078 _E("Failed to get reply message");
1083 dbus_pending_call_unref(pending);
1085 if (!dbus_message_iter_init(msg, &args)) {
1086 _E("Message has no arguments!");
1088 } else if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_INT32) {
1089 _E("Argument is not integer! type(%d)",
1090 dbus_message_iter_get_arg_type(&args));
1093 dbus_message_iter_get_basic(&args, &i);
1097 _D("Result: %d", *result);
1100 dbus_message_unref(msg);
1103 dbus_connection_close(conn);
1105 if (dbus_error_is_set(&err)) {
1106 _E("D-Bus error(%s)", err.message);
1107 dbus_error_free(&err);
1113 static DBusMessage *__create_tep_mount_message(void *user_data)
1115 DBusMessage *message;
1116 DBusMessageIter args;
1118 const char *tep_path = (const char *)user_data;
1120 message = dbus_message_new_method_call(TEP_BUS_NAME,
1123 TEP_IS_MOUNTED_METHOD);
1125 _E("Message is nullptr");
1129 dbus_message_iter_init_append(message, &args);
1130 r = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &tep_path);
1132 _E("Out of memory");
1133 dbus_message_unref(message);
1140 static int __is_tep_mount_done(const char *tep_path)
1145 ret = __dbus_send_message(__create_tep_mount_message,
1146 (void *)tep_path, 500, &result);
1148 _E("Failed to send message");
1153 static int __check_tep_mount(const char *tep_path)
1161 while (cnt < MAX_TEP_IS_MOUNT_RETRY_CNT) {
1162 r = __is_tep_mount_done(tep_path);
1170 _E("Not able to mount within 5 sec: %s", tep_path);
1177 int _wait_tep_mount(bundle *b)
1182 const char **tep_paths;
1184 tep_paths = bundle_get_str_array(b, AUL_K_TEP_PATH, &len);
1188 for (i = 0; i < len; ++i) {
1189 r = __check_tep_mount(tep_paths[i]);
1194 _I("Mount has been done.");
1198 static int __create_app_socket(int pid, uid_t uid)
1201 char path[PATH_MAX];
1202 struct sockaddr_un addr = {
1203 .sun_family = AF_UNIX,
1206 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
1208 if (errno == EINVAL) {
1209 fd = socket(AF_UNIX, SOCK_STREAM, 0);
1211 _E("Second chance - socket create errno(%d)",
1216 _E("Failed to create socket. errno(%d)", errno);
1221 snprintf(path, sizeof(path), "/run/aul/apps/%u/%d", uid, pid);
1222 if (mkdir(path, 0700) != 0) {
1223 if (errno == EEXIST) {
1224 if (access(path, R_OK) != 0) {
1225 _E("Failed to access %s. errno(%d)",
1231 _E("Failed to access %s. errno(%d)", path, errno);
1237 snprintf(addr.sun_path, sizeof(addr.sun_path),
1238 "/run/aul/apps/%u/%d/.app-sock", uid, pid);
1239 unlink(addr.sun_path);
1241 if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
1242 _E("Failed to bind socket(%d), errno(%d)", fd, errno);
1247 if (_set_sock_option(fd, 0) < 0) {
1248 _E("Failed to set sock option");
1253 if (listen(fd, 128) < 0) {
1254 _E("Failed to listen %d, errno(%d)", fd, errno);
1262 int _prepare_app_socket(void)
1267 fd = __create_app_socket(getpid(), getuid());
1271 snprintf(buf, sizeof(buf), "%d", fd);
1272 setenv("AUL_LISTEN_FD", buf, 1);
1277 struct package_info_s {
1282 static DBusMessage *__create_app2sd_message(void *user_data)
1284 struct package_info_s *pkg_info = (struct package_info_s *)user_data;
1285 DBusMessage *message;
1286 DBusMessageIter args;
1289 _D("[__APP2SD__] package(%s), uid(%u)", pkg_info->id, pkg_info->uid);
1291 message = dbus_message_new_method_call(APP2SD_BUS_NAME,
1293 APP2SD_INTERFACE_NAME,
1294 APP2SD_ONDEMANDSETUPINIT_METHOD);
1296 _E("Message is nullptr");
1300 dbus_message_iter_init_append(message, &args);
1301 r = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,
1304 _E("Failed to append pkgid");
1305 dbus_message_unref(message);
1309 r = dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32,
1312 _E("Failed to append uid");
1313 dbus_message_unref(message);
1320 int _enable_external_pkg(bundle *b, const char *pkgid, uid_t pkg_uid)
1322 const char *installed_storage;
1326 struct package_info_s pkg_info = {
1331 installed_storage = bundle_get_val(b, AUL_K_INSTALLED_STORAGE);
1332 if (!installed_storage || strcmp(installed_storage, "external") != 0)
1336 ret = __dbus_send_message(__create_app2sd_message,
1337 &pkg_info, 500, &result);
1339 _E("Failed to send message");
1341 usleep(APP2SD_WAIT_USEC);
1346 } while (retry_cnt <= APP2SD_RETRY_MAX);
1348 _D("[__APP2SD__] result(%d)", result);
1353 int _verify_proc_caps(void)
1356 cap_flag_value_t eff_state;
1357 cap_flag_value_t inh_state;
1358 cap_value_t value = CAP_SETGID;
1361 cap_d = cap_get_proc();
1363 _E("Failed to get cap from proc. pid(%d)", getpid());
1367 r = cap_get_flag(cap_d, value, CAP_INHERITABLE, &inh_state);
1369 _E("Failed to get cap inh - errno(%d)", errno);
1374 r = cap_get_flag(cap_d, value, CAP_EFFECTIVE, &eff_state);
1376 _E("Failed to get cap eff - errno(%d)", errno);
1381 if ((inh_state != CAP_SET) || (eff_state != CAP_SET)) {
1382 _E("The process(%d) doesn't have %d cap",
1392 int _prepare_id_file(void)
1394 char path[PATH_MAX];
1397 snprintf(path, sizeof(path), "/run/aul/apps/%u/%d/%s",
1398 getuid(), getpid(), getenv("AUL_APPID"));
1399 fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0600);
1401 _E("Failed to create %s. errno(%d)", path, errno);
1409 static int __send_raw(int fd, int cmd, unsigned char *data, int datalen)
1414 pkt = (app_pkt_t *)calloc(1, sizeof(app_pkt_t) + datalen);
1416 _E("Out of memory");
1423 memcpy(pkt->data, data, pkt->len);
1425 ret = _send_pkt_raw(fd, pkt);
1436 int _send_message_to_logger(const char *tag, const char *format, ...)
1438 char fmt[PATH_MAX - 256];
1444 snprintf(buf, sizeof(buf), "%s/daemons/%u/.launchpad-logger-sock",
1445 SOCKET_PATH, getuid());
1446 fd = __create_client_socket(buf);
1450 va_start(ap, format);
1451 vsnprintf(fmt, sizeof(fmt), format, ap);
1454 snprintf(buf, sizeof(buf), "%s: %s", tag, fmt);
1455 ret = __send_raw(fd, 0, (unsigned char *)buf, strlen(buf) + 1);
1466 void _print_hwc_log(const char *format, ...)
1471 va_start(ap, format);
1472 vsnprintf(buf, sizeof(buf), format, ap);
1475 prctl(PR_TASK_PERF_USER_TRACE, buf, strlen(buf));