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);
67 static int _muse_get_valid_fd_count(int *fds)
70 for (idx = 0; idx < MUSE_NUM_FD; idx++) {
71 if (fds[idx] == MUSE_ERR)
77 static void _muse_msg_json_set_error(muse_core_msg_parse_err_e *err, int jerr)
81 case json_tokener_success:
82 *err = MUSE_MSG_PARSE_ERROR_NONE;
84 case json_tokener_continue:
85 *err = MUSE_MSG_PARSE_ERROR_CONTINUE;
88 *err = MUSE_MSG_PARSE_ERROR_OTHER;
94 static json_object *_muse_msg_json_tokener_parse_len(const char *str, int *len, muse_core_msg_parse_err_e *err)
96 struct json_tokener *tok = NULL;
97 struct json_object *obj = NULL;
100 muse_return_val_if_fail(str, NULL);
102 tok = json_tokener_new();
105 LOGE("tokener creation error");
109 str_len = strlen(str);
110 obj = json_tokener_parse_ex(tok, str, str_len);
113 LOGE("parsing error : [length : %d] %s", str_len, str);
118 *len = tok->char_offset;
120 if (tok->err != json_tokener_success) {
121 LOGE("Json Error(%d) : %s", tok->err, json_tokener_error_desc(tok->err));
122 json_object_put(obj);
125 _muse_msg_json_set_error(err, tok->err);
129 json_tokener_free(tok);
134 static gboolean _muse_msg_is_mem_ptr_valid(gpointer ptr)
136 size_t page_size = sysconf(_SC_PAGESIZE);
137 gpointer base = (gpointer)((size_t)ptr / page_size * page_size);
139 return msync(base, page_size, MS_ASYNC) == 0;
142 static void _muse_msg_json_factory_args(json_object *jobj, va_list ap)
149 while ((type = va_arg(ap, int)) != 0) {
150 name = va_arg(ap, char *);
153 json_object_object_add(jobj, name, json_object_new_int(va_arg(ap, int32_t)));
155 case MUSE_TYPE_INT64:
156 json_object_object_add(jobj, name, json_object_new_int64(va_arg(ap, int64_t)));
158 case MUSE_TYPE_POINTER:
159 if (sizeof(intptr_t) == 8)
160 json_object_object_add(jobj, name, json_object_new_int64(va_arg(ap, intptr_t)));
162 json_object_object_add(jobj, name, json_object_new_int(va_arg(ap, intptr_t)));
164 case MUSE_TYPE_DOUBLE:
165 json_object_object_add(jobj, name, json_object_new_double(va_arg(ap, double)));
167 case MUSE_TYPE_STRING:
168 json_object_object_add(jobj, name, json_object_new_string(va_arg(ap, char *)));
170 case MUSE_TYPE_ARRAY:
171 len = va_arg(ap, int);
172 value = va_arg(ap, int *);
173 jarr = json_object_new_array();
175 for (idx = 0; idx < len; idx++)
176 json_object_array_add(jarr, json_object_new_int(value[idx]));
177 json_object_object_add(jobj, name, jarr);
180 LOGE("Unexpected type");
185 static json_object *_muse_msg_json_find_obj(json_object *jobj, const char *find_key)
189 muse_return_val_if_fail(jobj, NULL);
191 muse_return_val_if_fail(find_key, NULL);
193 key_len = strlen(find_key);
195 json_object_object_foreach(jobj, key, val) {
196 if (strlen(key) == key_len && !memcmp(key, find_key, key_len))
203 static gboolean _muse_msg_json_get_obj_value(json_object *obj, muse_core_msg_type_e m_type, void *data)
205 int j_type, idx, len;
207 const char *src = NULL;
209 muse_return_val_if_fail(obj, FALSE);
210 muse_return_val_if_fail(data, FALSE);
212 j_type = json_object_get_type(obj);
215 LOGD("json_type_null");
217 case json_type_double:
218 *(double *)data = json_object_get_double(obj);
221 if (m_type == MUSE_TYPE_ANY || m_type == MUSE_TYPE_INT) {
222 *(int32_t *)data = json_object_get_int(obj);
223 } else if (m_type == MUSE_TYPE_INT64) {
224 *(int64_t *)data = json_object_get_int64(obj);
225 } else if (m_type == MUSE_TYPE_POINTER) {
226 if (!_muse_msg_is_mem_ptr_valid(obj)) {
227 LOGE("memory pointer is not valid");
230 if (sizeof(intptr_t) == 8)
231 *(intptr_t *)data = json_object_get_int64(obj);
233 *(intptr_t *)data = json_object_get_int(obj);
234 } else if (m_type == MUSE_TYPE_DOUBLE) {
235 *(double *)data = json_object_get_double(obj);
238 case json_type_object:
240 case json_type_string:
241 src = json_object_get_string(obj);
242 muse_return_val_if_fail(src, FALSE);
243 g_strlcpy((gchar *)data, src, MUSE_MSG_MAX_LENGTH);
245 case json_type_array:
246 int_data = (int *)data;
247 len = json_object_array_length(obj);
248 for (idx = 0; idx < len; idx++)
249 int_data[idx] = json_object_get_int(json_object_array_get_idx(obj, idx));
252 LOGE("The value (%d) of json type is invalid", j_type);
259 void muse_core_log_cmd_info(char *cmd)
262 char buf[MUSE_MSG_LEN_MAX];
264 muse_return_if_fail(cmd);
266 fp = popen(cmd, "r");
269 while (fgets(buf, MUSE_MSG_LEN_MAX, fp))
272 if (pclose(fp) == -1)
273 LOGE("Fail to pclose");
277 bool muse_server_is_ready(void)
279 return access(MUSE_SERVER_READY, F_OK) == 0;
282 int muse_core_connection_close(int sock_fd)
284 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
286 if (!muse_core_fd_is_valid(sock_fd)) {
287 if (sock_fd != STDIN_FILENO)
288 LOGE("[%d] invalid socket", sock_fd);
289 return MM_ERROR_INVALID_ARGUMENT;
292 if (shutdown(sock_fd, SHUT_RDWR) == MUSE_ERR) {
293 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
294 LOGE("[%d] failed to shutdown [error %s %d]", sock_fd, err_msg, errno);
297 if (close(sock_fd) == MUSE_ERR) {
298 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
299 LOGE("[%d] failed to close [error %s %d]", sock_fd, err_msg, errno);
302 muse_core_dump_fd_state(sock_fd);
304 g_mutex_lock(&fd_state_lock);
306 if (!g_hash_table_remove(fd_state_table, GINT_TO_POINTER(sock_fd)))
307 LOGW("fail : remove fd %d from table[%p]", sock_fd, fd_state_table);
309 g_mutex_unlock(&fd_state_lock);
311 return MM_ERROR_NONE;
314 int muse_core_set_nonblocking(int fd, bool value)
316 int flags = fcntl(fd, F_GETFL, NULL);
317 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
320 flags = value ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK);
321 if (fcntl(fd, F_SETFL, flags) == -1) {
322 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
323 LOGE("fcntl (%d, F_SETFL, %d) [error %s %d]", fd, flags, err_msg, errno);
324 return MM_ERROR_FILE_INTERNAL;
326 LOGD("fcntl (%d, F_SETFL)", fd);
329 LOGE("failed to get flags for %d", fd);
330 return MM_ERROR_FILE_INTERNAL;
333 return MM_ERROR_NONE;
336 int muse_core_set_socket_timeout(int sock_fd, int timeout_sec)
338 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
343 tv.tv_sec = timeout_sec;
346 if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, (socklen_t)sizeof(tv)) == MUSE_ERR) {
347 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
348 LOGE("[%d] Failed to set socket send timeout option [error %s %d]", sock_fd, err_msg, errno);
349 return MM_ERROR_UNKNOWN;
352 if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, (socklen_t)sizeof(tv)) == MUSE_ERR) {
353 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
354 LOGE("[%d] Failed to set socket recv timeout option [error %s %d]", sock_fd, err_msg, errno);
355 return MM_ERROR_UNKNOWN;
360 return MM_ERROR_NONE;
363 bool muse_core_fd_is_valid(int fd)
365 muse_core_update_fd_state(fd);
366 return (fcntl(fd, F_GETFL) != MUSE_ERR || errno != EBADF) && (fd > STDERR_FILENO);
369 void muse_core_fd_close(int fd)
371 if (!muse_core_fd_is_valid(fd)) {
372 LOGW("%d is invalid fd", fd);
380 int muse_core_msg_send(int sock_fd, const char *msg)
382 muse_return_val_if_fail(msg, MM_ERROR_INVALID_ARGUMENT);
383 return muse_core_msg_send_fd(sock_fd, NULL, msg);
386 int muse_core_msg_send_fd(int sock_fd, int *fds, const char *buf)
388 int ret = MM_ERROR_NONE;
389 muse_msg_info_t msg_info = {0,};
390 struct cmsghdr *cptr;
393 char data[CMSG_SPACE(sizeof(int) * MUSE_NUM_FD)];
394 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
398 muse_return_val_if_fail(buf, MM_ERROR_INVALID_ARGUMENT);
399 muse_return_val_if_fail(muse_core_fd_is_valid(sock_fd), MM_ERROR_INVALID_ARGUMENT);
402 msg_info.type = MUSE_MSG_TYPE_NORMAL;
404 msg_info.type = MUSE_MSG_TYPE_FDS;
406 msg_info.marker = MUSE_MSG_HEAD;
407 msg_info.size = strlen(buf);
409 g_mutex_lock(&msg_ipc_lock);
411 ret = send(sock_fd, &msg_info, sizeof(muse_msg_info_t), 0);
412 if (ret != sizeof(muse_msg_info_t)) {
413 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
414 LOGE("msg info [type : %s size : %d] send failed : %d [error %s %d]",
415 msg_type[msg_info.type], msg_info.size, ret, err_msg, errno);
420 if (msg_info.type == MUSE_MSG_TYPE_NORMAL) {
421 ret = send(sock_fd, buf, msg_info.size, 0);
422 if (ret != (int)msg_info.size) {
423 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
424 LOGE("[%s] send failed : %d [error %s %d]", buf, ret, err_msg, errno);
430 /* MUSE_MSG_TYPE_FDS */
431 memset(&iov, 0, sizeof(iov));
432 iov.iov_base = (void *)buf;
433 iov.iov_len = msg_info.size;
435 memset(&msg, 0, sizeof(msg));
441 msg.msg_control = data;
442 msg.msg_controllen = sizeof(data);
444 cptr = CMSG_FIRSTHDR(&msg);
446 fd_cnt = _muse_get_valid_fd_count(fds);
447 cptr->cmsg_len = CMSG_LEN(sizeof(int) * fd_cnt);
448 cptr->cmsg_level = SOL_SOCKET;
449 cptr->cmsg_type = SCM_RIGHTS;
450 fdptr = (int *)CMSG_DATA(cptr);
452 memcpy(fdptr, fds, sizeof(int) * fd_cnt);
454 /* the value of msg_controllen increases after memcpy so reassigns the original value */
455 msg.msg_controllen = cptr->cmsg_len;
458 if ((ret = sendmsg(sock_fd, &msg, 0)) == SEND_FAIL) {
459 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
460 LOGE("[%d] fail to send msg - [error %s %d]", sock_fd, err_msg, errno);
464 g_mutex_unlock(&msg_ipc_lock);
469 int muse_core_msg_recv(int sock_fd, char *msg, int msg_len)
471 muse_return_val_if_fail(msg, MM_ERROR_INVALID_ARGUMENT);
472 return muse_core_msg_recv_fd(sock_fd, msg, msg_len, NULL);
475 int muse_core_msg_recv_fd(int sock_fd, char *buf, int buf_len, int *out_fd)
479 struct cmsghdr *cptr;
482 muse_msg_info_t msg_info = {0,};
483 char data[CMSG_SPACE(sizeof(int) * MUSE_NUM_FD)];
484 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
486 muse_return_val_if_fail(buf, MM_ERROR_INVALID_ARGUMENT);
487 muse_return_val_if_fail(muse_core_fd_is_valid(sock_fd), MM_ERROR_INVALID_ARGUMENT);
489 /* get the msg type and length */
490 if (!muse_core_msg_recv_len(sock_fd, (char *)&msg_info, sizeof(muse_msg_info_t))) {
492 LOGE("[pid : %d] [fd : %d] msg info receive failed", pid, sock_fd);
493 muse_core_log_process_thread_info(pid);
497 if (msg_info.size > 0 && buf_len < msg_info.size) {
498 LOGE("stack overflow caution !! [recv buf's length (%d) must be larger than msg's length (%d)", buf_len, msg_info.size);
502 if (msg_info.marker != MUSE_MSG_HEAD) {
503 LOGE("invalid marker 0x%x", msg_info.marker);
507 if (msg_info.type == MUSE_MSG_TYPE_NORMAL) {
508 if (!muse_core_msg_recv_len(sock_fd, buf, msg_info.size)) {
509 LOGE("msg receive failed");
515 memset(&iov, 0, sizeof(iov));
516 iov.iov_base = (void *)buf;
517 iov.iov_len = msg_info.size;
519 memset(&msg, 0, sizeof(msg));
524 msg.msg_control = data;
525 msg.msg_controllen = sizeof(data);
527 if ((ret = recvmsg(sock_fd, &msg, 0)) == RECV_FAIL) {
528 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
529 LOGE("fail to receive msg [error %s %d]", err_msg, errno);
534 cptr = CMSG_FIRSTHDR(&msg);
536 memcpy(out_fd, CMSG_DATA(cptr), cptr->cmsg_len - CMSG_LEN(0));
545 char *muse_core_msg_new(int api, ...)
552 jobj = json_object_new_object();
554 muse_return_val_if_fail(jobj, NULL);
556 json_object_object_add(jobj, MSG_KEY_API, json_object_new_int(api));
559 _muse_msg_json_factory_args(jobj, ap);
562 jsonMsg = json_object_to_json_string(jobj);
563 sndMsg = g_strdup(jsonMsg);
565 if (api == API_CREATE)
566 SECURE_LOGD("%s", sndMsg);
568 json_object_put(jobj);
573 bool muse_core_msg_deserialize(const char *key, char *buf, int *parse_len,
574 muse_core_msg_parse_err_e *err, muse_core_msg_type_e m_type, void *data)
576 json_object *obj = NULL, *jobj = NULL;
579 muse_return_val_if_fail(key, false);
580 muse_return_val_if_fail(buf, false);
581 muse_return_val_if_fail(m_type >= MUSE_TYPE_INT && m_type < MUSE_TYPE_MAX, false);
582 muse_return_val_if_fail(data, false);
584 g_mutex_lock(&msg_lock);
586 jobj = _muse_msg_json_tokener_parse_len(buf, parse_len, err);
588 LOGE("jobj is NULL");
589 g_mutex_unlock(&msg_lock);
593 obj = _muse_msg_json_find_obj(jobj, key);
595 LOGE("\"%s\" key is not founded", key);
596 json_object_put(jobj);
597 g_mutex_unlock(&msg_lock);
601 ret = (bool)_muse_msg_json_get_obj_value(obj, m_type, data);
603 json_object_put(jobj);
605 g_mutex_unlock(&msg_lock);
610 void muse_core_msg_free(char *msg)
615 void *muse_core_msg_object_new(char *str, int *parse_len, muse_core_msg_parse_err_e *err)
619 muse_return_val_if_fail(str, NULL);
621 g_mutex_lock(&msg_lock);
623 jobj = (void *)_muse_msg_json_tokener_parse_len(str, parse_len, err);
625 g_mutex_unlock(&msg_lock);
630 bool muse_core_msg_object_get_value(const char *key, void *jobj, muse_core_msg_type_e m_type, void *data)
635 muse_return_val_if_fail(key, false);
636 muse_return_val_if_fail(jobj, false);
637 muse_return_val_if_fail(data, false);
638 muse_return_val_if_fail(m_type >= MUSE_TYPE_INT && m_type < MUSE_TYPE_MAX, false);
640 g_mutex_lock(&msg_lock);
642 obj = _muse_msg_json_find_obj((json_object *)jobj, key);
644 LOGE("\"%s\" key is not found", key);
645 g_mutex_unlock(&msg_lock);
649 ret = (bool)_muse_msg_json_get_obj_value(obj, m_type, data);
651 g_mutex_unlock(&msg_lock);
656 void muse_core_msg_object_free(void *jobj)
658 muse_return_if_fail(jobj);
660 g_mutex_lock(&msg_lock);
662 json_object_put((json_object *)jobj);
664 g_mutex_unlock(&msg_lock);
667 bool muse_core_msg_recv_len(int fd, char *buf, int msg_len)
671 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
673 if (!muse_core_fd_is_valid(fd) || !buf || msg_len <= 0) {
674 LOGE("invalid param : fd %d, buf %p, msg_len %d", fd, buf, msg_len);
679 recv_len = recv(fd, buf + offset, msg_len - offset, 0);
681 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
682 LOGE("[%d] recv failed [error %s %d]", fd, err_msg, errno);
684 } else if (recv_len == 0) {
685 LOGD("[%d] EOF", fd);
690 } while (offset < msg_len);
692 if (offset != msg_len) {
693 LOGE("invalid length received : try %d -> result %d", msg_len, offset);
700 void muse_core_change_time_format(int val, char *time_buf)
702 int sec, min, hour, day;
704 muse_return_if_fail(time_buf);
706 min = val / MUSE_MIN_SEC_VALUE;
707 hour = min / MUSE_HOUR_MIN_VALUE;
708 day = hour / MUSE_DAY_HOUR_VALUE;
710 sec = val % MUSE_MIN_SEC_VALUE;
711 min = min % MUSE_HOUR_MIN_VALUE;
712 hour = hour % MUSE_DAY_HOUR_VALUE;
714 snprintf(time_buf, MUSE_MSG_TIME_LEN, "%dd %dh %dm %ds", day, hour, min, sec);
717 void muse_core_dump_fd_state(int fd)
720 char time_buf[MUSE_MSG_TIME_LEN];
722 g_mutex_lock(&fd_state_lock);
723 sec = GPOINTER_TO_INT(g_hash_table_lookup(fd_state_table, GINT_TO_POINTER(fd)));
724 muse_core_change_time_format(sec, time_buf);
725 LOGI("[%d] %s", fd, time_buf);
726 g_mutex_unlock(&fd_state_lock);
729 void muse_core_update_fd_state(int fd)
733 g_mutex_lock(&fd_state_lock);
736 fd_state_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
738 muse_core_get_cur_time(&tv, NULL);
739 g_hash_table_insert(fd_state_table, GINT_TO_POINTER(fd), GINT_TO_POINTER((int)tv.tv_sec));
741 g_mutex_unlock(&fd_state_lock);
744 void muse_core_create_fd_table(void)
746 g_mutex_lock(&fd_state_lock);
748 if (fd_state_table) {
749 LOGW("fd state table [%p] is already created", fd_state_table);
753 fd_state_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
755 LOGE("fail to create new fd state table");
757 g_mutex_unlock(&fd_state_lock);
760 void muse_core_remove_all_fd_table(void)
762 g_mutex_lock(&fd_state_lock);
763 g_hash_table_remove_all(fd_state_table);
764 g_mutex_unlock(&fd_state_lock);
767 void muse_core_destroy_fd_table(void)
769 g_mutex_lock(&fd_state_lock);
770 g_hash_table_destroy(fd_state_table);
771 fd_state_table = NULL;
772 g_mutex_unlock(&fd_state_lock);
775 void muse_core_get_cur_time(struct timespec *time, char *time_buf)
777 char cur_time[MUSE_MSG_LEN];
781 muse_return_if_fail(clock_gettime(CLOCK_MONOTONIC, &tv) == 0);
787 strftime(cur_time, MUSE_MSG_LEN, STR_TIME_FORMAT, localtime_r(&(tv.tv_sec), &newtime));
788 snprintf(time_buf, MUSE_MSG_TIME_LEN, "%s.%03ld", cur_time, tv.tv_nsec);
792 void muse_core_log_process_thread_info(int pid)
794 char cmd[MUSE_MSG_LEN_MAX];
796 snprintf(cmd, sizeof(cmd), "/bin/cat /proc/%d/status | /bin/grep Threads", pid);
797 muse_core_log_cmd_info(cmd);
800 void muse_core_log_process_opened_fds(int pid)
802 char dir_path[MUSE_MSG_LEN_MAX];
803 struct dirent *de = NULL;
806 snprintf(dir_path, sizeof(dir_path), "/proc/%d/fd", pid); /* /proc/%d/fd is directory */
807 dr = opendir(dir_path);
808 muse_return_if_fail(dr);
810 LOGI("directory path : %s", dir_path);
812 while ((de = readdir(dr)) != NULL)
813 LOGW("%s\n", de->d_name);
818 void muse_core_log_process_cpu_memory(int pid)
820 char cmd[MUSE_MSG_LEN_MAX];
822 snprintf(cmd, sizeof(cmd), "/bin/ps -Lo pcpu,pmem,tid,comm -p %d", pid);
823 muse_core_log_cmd_info(cmd);
826 int muse_core_get_process_cpu_usage(int pid)
830 char cmd[MUSE_MSG_LEN_MAX];
831 char buf[MUSE_MSG_LEN_MAX];
833 snprintf(cmd, sizeof(cmd), "/bin/ps -Lo pcpu,pmem,tid,comm -p %d", pid);
835 fp = popen(cmd, "r");
838 while (fgets(buf, MUSE_MSG_LEN_MAX, fp)) {
840 cpu += atoi(g_strstrip(buf));
843 if (pclose(fp) == -1)
844 LOGE("Fail to pclose");
850 void muse_core_log_file_list(const char *path)
852 char cmd[MUSE_MSG_LEN_MAX];
854 snprintf(cmd, sizeof(cmd), "/bin/ls -alt %s", path);
855 muse_core_log_cmd_info(cmd);
858 void muse_core_remove_symlink(const char *path)
860 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
863 muse_return_if_fail(path);
865 r = realpath(path, NULL);
867 if (strncmp(r, path, strlen(path) + 1) != 0) {
868 LOGW("symbolic link exists [%s] -> [%s]", path, r);
873 if (errno != ENOENT) {
874 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
875 LOGE("realpath failed [error %s %d]", err_msg, errno);