4 * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: YoungHun Kim <yh8004.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #include "muse_core_internal.h"
27 #define LOG_TAG "MUSED_CORE"
29 #define STR_TIME_FORMAT "%m-%d %H:%M:%S"
30 #define MUSE_MIN_SEC_VALUE 60
31 #define MUSE_HOUR_MIN_VALUE 60
32 #define MUSE_DAY_HOUR_VALUE 24
34 #define MUSE_WATCHDOG_CHECK_PERIOD 10
35 #define MUSE_WATCHDOG_CHECK_COUNT 3
36 #define MUSE_WATCHDOG_TIMER_PERIOD 5
38 static const char *msg_type[] = { "normal type", "fds type" };
40 static GMutex msg_lock;
41 static GMutex msg_ipc_lock;
43 static GMutex fd_state_lock;
44 static GHashTable *fd_state_table;
46 static int _muse_get_valid_fd_count(int *fds);
47 static void _muse_msg_json_set_error(muse_core_msg_parse_err_e *err, int jerr);
48 static json_object *_muse_msg_json_tokener_parse_len(const char *str, int *len, muse_core_msg_parse_err_e *err);
49 static gboolean _muse_msg_is_mem_ptr_valid(gpointer ptr);
50 static void _muse_msg_json_factory_args(json_object *jobj, va_list ap);
51 static json_object *_muse_msg_json_find_obj(json_object *jobj, const char *find_key);
52 static gboolean _muse_msg_json_get_obj_value(json_object *obj, muse_core_msg_type_e m_type, void *data);
55 void muse_core_gcov_flush(void)
60 void muse_core_setenv(const char *name, const char *value, int replace)
62 setenv(name, value, replace);
66 static int _muse_get_valid_fd_count(int *fds)
69 for (idx = 0; idx < MUSE_NUM_FD; idx++) {
70 if (fds[idx] == MUSE_ERR)
76 static void _muse_msg_json_set_error(muse_core_msg_parse_err_e *err, int jerr)
80 case json_tokener_success:
81 *err = MUSE_MSG_PARSE_ERROR_NONE;
83 case json_tokener_continue:
84 *err = MUSE_MSG_PARSE_ERROR_CONTINUE;
87 *err = MUSE_MSG_PARSE_ERROR_OTHER;
93 static json_object *_muse_msg_json_tokener_parse_len(const char *str, int *len, muse_core_msg_parse_err_e *err)
95 struct json_tokener *tok = NULL;
96 struct json_object *obj = NULL;
99 muse_return_val_if_fail(str, NULL);
101 tok = json_tokener_new();
104 LOGE("tokener creation error");
108 str_len = strlen(str);
109 obj = json_tokener_parse_ex(tok, str, str_len);
112 LOGE("parsing error : [length : %d] %s", str_len, str);
117 *len = tok->char_offset;
119 if (tok->err != json_tokener_success) {
120 LOGE("Json Error(%d) : %s", tok->err, json_tokener_error_desc(tok->err));
121 json_object_put(obj);
124 _muse_msg_json_set_error(err, tok->err);
128 json_tokener_free(tok);
133 static gboolean _muse_msg_is_mem_ptr_valid(gpointer ptr)
135 size_t page_size = sysconf(_SC_PAGESIZE);
136 gpointer base = (gpointer)((size_t)ptr / page_size * page_size);
138 return msync(base, page_size, MS_ASYNC) == 0;
141 static void _muse_msg_json_factory_args(json_object *jobj, va_list ap)
148 while ((type = va_arg(ap, int)) != 0) {
149 name = va_arg(ap, char *);
152 json_object_object_add(jobj, name, json_object_new_int(va_arg(ap, int32_t)));
154 case MUSE_TYPE_INT64:
155 json_object_object_add(jobj, name, json_object_new_int64(va_arg(ap, int64_t)));
157 case MUSE_TYPE_POINTER:
158 if (sizeof(intptr_t) == 8)
159 json_object_object_add(jobj, name, json_object_new_int64(va_arg(ap, intptr_t)));
161 json_object_object_add(jobj, name, json_object_new_int(va_arg(ap, intptr_t)));
163 case MUSE_TYPE_DOUBLE:
164 json_object_object_add(jobj, name, json_object_new_double(va_arg(ap, double)));
166 case MUSE_TYPE_STRING:
167 json_object_object_add(jobj, name, json_object_new_string(va_arg(ap, char *)));
169 case MUSE_TYPE_ARRAY:
170 len = va_arg(ap, int);
171 value = va_arg(ap, int *);
172 jarr = json_object_new_array();
174 for (idx = 0; idx < len; idx++)
175 json_object_array_add(jarr, json_object_new_int(value[idx]));
176 json_object_object_add(jobj, name, jarr);
179 LOGE("Unexpected type");
184 static json_object *_muse_msg_json_find_obj(json_object *jobj, const char *find_key)
188 muse_return_val_if_fail(jobj, NULL);
190 muse_return_val_if_fail(find_key, NULL);
192 key_len = strlen(find_key);
194 json_object_object_foreach(jobj, key, val) {
195 if (strlen(key) == key_len && !memcmp(key, find_key, key_len))
202 static gboolean _muse_msg_json_get_obj_value(json_object *obj, muse_core_msg_type_e m_type, void *data)
204 int j_type, idx, len;
206 const char *src = NULL;
208 muse_return_val_if_fail(obj, FALSE);
209 muse_return_val_if_fail(data, FALSE);
211 j_type = json_object_get_type(obj);
214 LOGD("json_type_null");
216 case json_type_double:
217 *(double *)data = json_object_get_double(obj);
220 if (m_type == MUSE_TYPE_ANY || m_type == MUSE_TYPE_INT) {
221 *(int32_t *)data = json_object_get_int(obj);
222 } else if (m_type == MUSE_TYPE_INT64) {
223 *(int64_t *)data = json_object_get_int64(obj);
224 } else if (m_type == MUSE_TYPE_POINTER) {
225 if (!_muse_msg_is_mem_ptr_valid(obj)) {
226 LOGE("memory pointer is not valid");
229 if (sizeof(intptr_t) == 8)
230 *(intptr_t *)data = json_object_get_int64(obj);
232 *(intptr_t *)data = json_object_get_int(obj);
233 } else if (m_type == MUSE_TYPE_DOUBLE) {
234 *(double *)data = json_object_get_double(obj);
237 case json_type_object:
239 case json_type_string:
240 src = json_object_get_string(obj);
241 muse_return_val_if_fail(src, FALSE);
242 g_strlcpy((gchar *)data, src, MUSE_MSG_MAX_LENGTH);
244 case json_type_array:
245 int_data = (int *)data;
246 len = json_object_array_length(obj);
247 for (idx = 0; idx < len; idx++)
248 int_data[idx] = json_object_get_int(json_object_array_get_idx(obj, idx));
251 LOGE("The value (%d) of json type is invalid", j_type);
258 void muse_core_log_cmd_info(char *cmd)
261 char buf[MUSE_MSG_LEN_MAX];
263 muse_return_if_fail(cmd);
265 fp = popen(cmd, "r");
268 while (fgets(buf, MUSE_MSG_LEN_MAX, fp))
271 if (pclose(fp) == -1)
272 LOGE("Fail to pclose");
276 bool muse_server_is_ready(void)
278 return access(MUSE_SERVER_READY, F_OK) == 0;
281 int muse_core_connection_close(int sock_fd)
283 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
284 g_autoptr(GMutexLocker) locker = NULL;
286 if (!muse_core_fd_is_valid(sock_fd)) {
287 LOGE("[%d] invalid socket", sock_fd);
288 return MM_ERROR_INVALID_ARGUMENT;
291 if (shutdown(sock_fd, SHUT_RDWR) == MUSE_ERR) {
292 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
293 LOGE("[%d] failed to shutdown [error %s %d]", sock_fd, err_msg, errno);
296 if (close(sock_fd) == MUSE_ERR) {
297 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
298 LOGE("[%d] failed to close [error %s %d]", sock_fd, err_msg, errno);
301 muse_core_dump_fd_state(sock_fd);
303 locker = g_mutex_locker_new(&fd_state_lock);
305 if (!g_hash_table_remove(fd_state_table, GINT_TO_POINTER(sock_fd)))
306 LOGW("fail : remove fd %d from table[%p]", sock_fd, fd_state_table);
308 return MM_ERROR_NONE;
311 int muse_core_set_nonblocking(int fd, bool value)
313 int flags = fcntl(fd, F_GETFL, NULL);
314 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
317 flags = value ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK);
318 if (fcntl(fd, F_SETFL, flags) == -1) {
319 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
320 LOGE("fcntl (%d, F_SETFL, %d) [error %s %d]", fd, flags, err_msg, errno);
321 return MM_ERROR_FILE_INTERNAL;
323 LOGD("fcntl (%d, F_SETFL)", fd);
326 LOGE("failed to get flags for %d", fd);
327 return MM_ERROR_FILE_INTERNAL;
330 return MM_ERROR_NONE;
333 int muse_core_set_socket_timeout(int sock_fd, int timeout_sec)
335 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
340 tv.tv_sec = timeout_sec;
343 if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, (socklen_t)sizeof(tv)) == MUSE_ERR) {
344 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
345 LOGE("[%d] Failed to set socket send timeout option [error %s %d]", sock_fd, err_msg, errno);
346 return MM_ERROR_UNKNOWN;
349 if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, (socklen_t)sizeof(tv)) == MUSE_ERR) {
350 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
351 LOGE("[%d] Failed to set socket recv timeout option [error %s %d]", sock_fd, err_msg, errno);
352 return MM_ERROR_UNKNOWN;
357 return MM_ERROR_NONE;
360 bool muse_core_fd_is_valid(int fd)
362 muse_core_update_fd_state(fd);
363 return (fcntl(fd, F_GETFL) != MUSE_ERR || errno != EBADF) && (fd > STDERR_FILENO);
366 void muse_core_fd_close(int fd)
368 if (!muse_core_fd_is_valid(fd)) {
369 LOGW("%d is invalid fd", fd);
377 int muse_core_msg_send(int sock_fd, const char *msg)
379 muse_return_val_if_fail(msg, MM_ERROR_INVALID_ARGUMENT);
380 return muse_core_msg_send_fd(sock_fd, NULL, msg);
383 int muse_core_msg_send_fd(int sock_fd, int *fds, const char *buf)
385 int ret = MM_ERROR_NONE;
386 muse_msg_info_t msg_info = {0,};
387 struct cmsghdr *cptr;
390 char data[CMSG_SPACE(sizeof(int) * MUSE_NUM_FD)];
391 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
394 g_autoptr(GMutexLocker) locker = NULL;
396 muse_return_val_if_fail(buf, MM_ERROR_INVALID_ARGUMENT);
397 muse_return_val_if_fail(muse_core_fd_is_valid(sock_fd), MM_ERROR_INVALID_ARGUMENT);
400 msg_info.type = MUSE_MSG_TYPE_NORMAL;
402 msg_info.type = MUSE_MSG_TYPE_FDS;
404 msg_info.marker = MUSE_MSG_HEAD;
405 msg_info.size = strlen(buf);
407 locker = g_mutex_locker_new(&msg_ipc_lock);
409 ret = send(sock_fd, &msg_info, sizeof(muse_msg_info_t), 0);
410 if (ret != sizeof(muse_msg_info_t)) {
411 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
412 LOGE("[fd : %d] msg info [type : %s size : %zu] send failed : %d [error %s %d]",
413 sock_fd, msg_type[msg_info.type], msg_info.size, ret, err_msg, errno);
418 if (msg_info.type == MUSE_MSG_TYPE_NORMAL) {
419 ret = send(sock_fd, buf, msg_info.size, 0);
420 if (ret != (int)msg_info.size) {
421 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
422 LOGE("[%s] send failed : %d [error %s %d]", buf, ret, err_msg, errno);
428 /* MUSE_MSG_TYPE_FDS */
429 memset(&iov, 0, sizeof(iov));
430 iov.iov_base = (void *)buf;
431 iov.iov_len = msg_info.size;
433 memset(&msg, 0, sizeof(msg));
439 msg.msg_control = data;
440 msg.msg_controllen = sizeof(data);
442 cptr = CMSG_FIRSTHDR(&msg);
444 fd_cnt = _muse_get_valid_fd_count(fds);
445 cptr->cmsg_len = CMSG_LEN(sizeof(int) * fd_cnt);
446 cptr->cmsg_level = SOL_SOCKET;
447 cptr->cmsg_type = SCM_RIGHTS;
448 fdptr = (int *)CMSG_DATA(cptr);
450 memcpy(fdptr, fds, sizeof(int) * fd_cnt);
452 /* the value of msg_controllen increases after memcpy so reassigns the original value */
453 msg.msg_controllen = cptr->cmsg_len;
456 if ((ret = sendmsg(sock_fd, &msg, 0)) == SEND_FAIL) {
457 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
458 LOGE("[%d] fail to send msg - [error %s %d]", sock_fd, err_msg, errno);
464 int muse_core_msg_recv(int sock_fd, char *msg, int msg_len)
466 muse_return_val_if_fail(msg, MM_ERROR_INVALID_ARGUMENT);
467 return muse_core_msg_recv_fd(sock_fd, msg, msg_len, NULL);
470 int muse_core_msg_recv_fd(int sock_fd, char *buf, int buf_len, int *out_fd)
474 struct cmsghdr *cptr;
477 muse_msg_info_t msg_info = {0,};
478 char data[CMSG_SPACE(sizeof(int) * MUSE_NUM_FD)];
479 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
481 muse_return_val_if_fail(buf, MM_ERROR_INVALID_ARGUMENT);
482 muse_return_val_if_fail(muse_core_fd_is_valid(sock_fd), MM_ERROR_INVALID_ARGUMENT);
484 /* get the msg type and length */
485 if (!muse_core_msg_recv_len(sock_fd, (char *)&msg_info, sizeof(muse_msg_info_t))) {
487 LOGE("[pid : %d] [fd : %d] msg info receive failed", pid, sock_fd);
488 muse_core_log_process_thread_info(pid);
492 if (msg_info.size > 0 && buf_len < (int)msg_info.size) {
493 LOGE("stack overflow caution !! [recv buf's length (%d) must be larger than msg's length (%zu)", buf_len, msg_info.size);
497 if (msg_info.marker != MUSE_MSG_HEAD) {
498 LOGE("invalid marker 0x%x", msg_info.marker);
502 if (msg_info.type == MUSE_MSG_TYPE_NORMAL) {
503 if (!muse_core_msg_recv_len(sock_fd, buf, msg_info.size)) {
504 LOGE("msg receive failed");
510 memset(&iov, 0, sizeof(iov));
511 iov.iov_base = (void *)buf;
512 iov.iov_len = msg_info.size;
514 memset(&msg, 0, sizeof(msg));
519 msg.msg_control = data;
520 msg.msg_controllen = sizeof(data);
522 if ((ret = recvmsg(sock_fd, &msg, 0)) == RECV_FAIL) {
523 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
524 LOGE("fail to receive msg [error %s %d]", err_msg, errno);
529 cptr = CMSG_FIRSTHDR(&msg);
531 memcpy(out_fd, CMSG_DATA(cptr), cptr->cmsg_len - CMSG_LEN(0));
540 char *muse_core_msg_new(int api, ...)
547 jobj = json_object_new_object();
549 muse_return_val_if_fail(jobj, NULL);
551 json_object_object_add(jobj, MSG_KEY_API, json_object_new_int(api));
554 _muse_msg_json_factory_args(jobj, ap);
557 jsonMsg = json_object_to_json_string(jobj);
558 sndMsg = g_strdup(jsonMsg);
560 if (api == API_CREATE)
561 SECURE_LOGD("%s", sndMsg);
563 json_object_put(jobj);
568 bool muse_core_msg_deserialize(const char *key, char *buf, int *parse_len,
569 muse_core_msg_parse_err_e *err, muse_core_msg_type_e m_type, void *data)
571 json_object *obj = NULL, *jobj = NULL;
573 g_autoptr(GMutexLocker) locker = NULL;
575 muse_return_val_if_fail(key, false);
576 muse_return_val_if_fail(buf, false);
577 muse_return_val_if_fail(m_type >= MUSE_TYPE_INT && m_type < MUSE_TYPE_MAX, false);
578 muse_return_val_if_fail(data, false);
580 locker = g_mutex_locker_new(&msg_lock);
582 jobj = _muse_msg_json_tokener_parse_len(buf, parse_len, err);
584 LOGE("jobj is NULL");
588 obj = _muse_msg_json_find_obj(jobj, key);
590 LOGE("\"%s\" key is not founded", key);
591 json_object_put(jobj);
595 ret = (bool)_muse_msg_json_get_obj_value(obj, m_type, data);
597 json_object_put(jobj);
602 void muse_core_msg_free(char *msg)
607 void *muse_core_msg_object_new(char *str, int *parse_len, muse_core_msg_parse_err_e *err)
609 muse_return_val_if_fail(str, NULL);
611 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&msg_lock);
613 return (void *)_muse_msg_json_tokener_parse_len(str, parse_len, err);
616 bool muse_core_msg_object_get_value(const char *key, void *jobj, muse_core_msg_type_e m_type, void *data)
619 g_autoptr(GMutexLocker) locker = NULL;
621 muse_return_val_if_fail(key, false);
622 muse_return_val_if_fail(jobj, false);
623 muse_return_val_if_fail(data, false);
624 muse_return_val_if_fail(m_type >= MUSE_TYPE_INT && m_type < MUSE_TYPE_MAX, false);
626 locker = g_mutex_locker_new(&msg_lock);
628 obj = _muse_msg_json_find_obj((json_object *)jobj, key);
630 LOGE("\"%s\" key is not found", key);
634 return (bool)_muse_msg_json_get_obj_value(obj, m_type, data);
637 void muse_core_msg_object_free(void *jobj)
639 muse_return_if_fail(jobj);
641 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&msg_lock);
643 json_object_put((json_object *)jobj);
646 bool muse_core_msg_recv_len(int fd, char *buf, int msg_len)
650 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
652 if (!muse_core_fd_is_valid(fd) || !buf || msg_len <= 0) {
653 LOGE("invalid param : fd %d, buf %p, msg_len %d", fd, buf, msg_len);
658 recv_len = recv(fd, buf + offset, msg_len - offset, 0);
660 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
661 LOGE("[%d] recv failed [error %s %d]", fd, err_msg, errno);
663 } else if (recv_len == 0) {
664 LOGD("[%d] EOF", fd);
669 } while (offset < msg_len);
671 if (offset != msg_len) {
672 LOGE("invalid length received : try %d -> result %d", msg_len, offset);
679 void muse_core_change_time_format(int val, char *time_buf)
681 int sec, min, hour, day;
683 muse_return_if_fail(time_buf);
685 min = val / MUSE_MIN_SEC_VALUE;
686 hour = min / MUSE_HOUR_MIN_VALUE;
687 day = hour / MUSE_DAY_HOUR_VALUE;
689 sec = val % MUSE_MIN_SEC_VALUE;
690 min = min % MUSE_HOUR_MIN_VALUE;
691 hour = hour % MUSE_DAY_HOUR_VALUE;
693 snprintf(time_buf, MUSE_MSG_TIME_LEN, "%dd %dh %dm %ds", day, hour, min, sec);
696 void muse_core_dump_fd_state(int fd)
699 char time_buf[MUSE_MSG_TIME_LEN];
701 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&fd_state_lock);
703 sec = GPOINTER_TO_INT(g_hash_table_lookup(fd_state_table, GINT_TO_POINTER(fd)));
704 muse_core_change_time_format(sec, time_buf);
705 LOGI("[%d] %s", fd, time_buf);
708 void muse_core_update_fd_state(int fd)
712 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&fd_state_lock);
715 fd_state_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
717 muse_core_get_cur_time(&tv, NULL);
718 g_hash_table_insert(fd_state_table, GINT_TO_POINTER(fd), GINT_TO_POINTER((int)tv.tv_sec));
721 gboolean muse_core_set_close_on_exec(int fd)
723 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
725 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
726 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
727 LOGE("unable to set FD_CLOEXEC on fd %d: %s", fd, err_msg);
734 void muse_core_create_fd_table(void)
736 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&fd_state_lock);
738 if (fd_state_table) {
739 LOGW("fd state table [%p] is already created", fd_state_table);
743 fd_state_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
745 LOGE("fail to create new fd state table");
748 void muse_core_remove_all_fd_table(void)
750 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&fd_state_lock);
751 g_hash_table_remove_all(fd_state_table);
754 void muse_core_destroy_fd_table(void)
756 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&fd_state_lock);
757 g_hash_table_destroy(fd_state_table);
758 fd_state_table = NULL;
761 void muse_core_get_cur_time(struct timespec *time, char *time_buf)
763 char cur_time[MUSE_MSG_LEN];
767 muse_return_if_fail(clock_gettime(CLOCK_MONOTONIC, &tv) == 0);
773 strftime(cur_time, MUSE_MSG_LEN, STR_TIME_FORMAT, localtime_r(&(tv.tv_sec), &newtime));
774 snprintf(time_buf, MUSE_MSG_TIME_LEN, "%s.%03ld", cur_time, tv.tv_nsec);
778 void muse_core_log_process_thread_info(int pid)
780 char cmd[MUSE_MSG_LEN_MAX];
782 snprintf(cmd, sizeof(cmd), "/bin/cat /proc/%d/status | /bin/grep Threads", pid);
783 muse_core_log_cmd_info(cmd);
786 void muse_core_log_process_opened_fds(int pid)
788 char dir_path[MUSE_MSG_LEN_MAX];
789 struct dirent *de = NULL;
792 snprintf(dir_path, sizeof(dir_path), "/proc/%d/fd", pid); /* /proc/%d/fd is directory */
793 dr = opendir(dir_path);
794 muse_return_if_fail(dr);
796 LOGI("directory path : %s", dir_path);
798 while ((de = readdir(dr)) != NULL)
799 LOGW("%s\n", de->d_name);
804 void muse_core_log_process_cpu_memory(int pid)
806 char cmd[MUSE_MSG_LEN_MAX];
808 snprintf(cmd, sizeof(cmd), "/bin/ps -Lo pcpu,pmem,tid,comm -p %d", pid);
809 muse_core_log_cmd_info(cmd);
812 int muse_core_get_process_cpu_usage(int pid)
816 char cmd[MUSE_MSG_LEN_MAX];
817 char buf[MUSE_MSG_LEN_MAX];
819 snprintf(cmd, sizeof(cmd), "/bin/ps -Lo pcpu,pmem,tid,comm -p %d", pid);
821 fp = popen(cmd, "r");
824 while (fgets(buf, MUSE_MSG_LEN_MAX, fp)) {
826 cpu += atoi(g_strstrip(buf));
829 if (pclose(fp) == -1)
830 LOGE("Fail to pclose");
836 void muse_core_log_file_list(const char *path)
838 char cmd[MUSE_MSG_LEN_MAX];
840 snprintf(cmd, sizeof(cmd), "/bin/ls -alt %s", path);
841 muse_core_log_cmd_info(cmd);
844 void muse_core_remove_symlink(const char *path)
846 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
849 muse_return_if_fail(path);
851 r = realpath(path, NULL);
853 if (strncmp(r, path, strlen(path)) != 0) {
854 LOGW("symbolic link exists [%s] -> [%s]", path, r);
859 if (errno != ENOENT) {
860 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
861 LOGE("realpath failed [error %s %d]", err_msg, errno);