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 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 g_mutex_lock(&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 g_mutex_unlock(&fd_state_lock);
310 return MM_ERROR_NONE;
313 int muse_core_set_nonblocking(int fd, bool value)
315 int flags = fcntl(fd, F_GETFL, NULL);
316 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
319 flags = value ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK);
320 if (fcntl(fd, F_SETFL, flags) == -1) {
321 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
322 LOGE("fcntl (%d, F_SETFL, %d) [error %s %d]", fd, flags, err_msg, errno);
323 return MM_ERROR_FILE_INTERNAL;
325 LOGD("fcntl (%d, F_SETFL)", fd);
328 LOGE("failed to get flags for %d", fd);
329 return MM_ERROR_FILE_INTERNAL;
332 return MM_ERROR_NONE;
335 int muse_core_set_socket_timeout(int sock_fd, int timeout_sec)
337 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
342 tv.tv_sec = timeout_sec;
345 if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, (socklen_t)sizeof(tv)) == MUSE_ERR) {
346 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
347 LOGE("[%d] Failed to set socket send timeout option [error %s %d]", sock_fd, err_msg, errno);
348 return MM_ERROR_UNKNOWN;
351 if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, (socklen_t)sizeof(tv)) == MUSE_ERR) {
352 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
353 LOGE("[%d] Failed to set socket recv timeout option [error %s %d]", sock_fd, err_msg, errno);
354 return MM_ERROR_UNKNOWN;
359 return MM_ERROR_NONE;
362 bool muse_core_fd_is_valid(int fd)
364 muse_core_update_fd_state(fd);
365 return (fcntl(fd, F_GETFL) != MUSE_ERR || errno != EBADF) && (fd > STDERR_FILENO);
368 void muse_core_fd_close(int fd)
370 if (!muse_core_fd_is_valid(fd)) {
371 LOGW("%d is invalid fd", fd);
379 int muse_core_msg_send(int sock_fd, const char *msg)
381 muse_return_val_if_fail(msg, MM_ERROR_INVALID_ARGUMENT);
382 return muse_core_msg_send_fd(sock_fd, NULL, msg);
385 int muse_core_msg_send_fd(int sock_fd, int *fds, const char *buf)
387 int ret = MM_ERROR_NONE;
388 muse_msg_info_t msg_info = {0,};
389 struct cmsghdr *cptr;
392 char data[CMSG_SPACE(sizeof(int) * MUSE_NUM_FD)];
393 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
397 muse_return_val_if_fail(buf, MM_ERROR_INVALID_ARGUMENT);
398 muse_return_val_if_fail(muse_core_fd_is_valid(sock_fd), MM_ERROR_INVALID_ARGUMENT);
401 msg_info.type = MUSE_MSG_TYPE_NORMAL;
403 msg_info.type = MUSE_MSG_TYPE_FDS;
405 msg_info.marker = MUSE_MSG_HEAD;
406 msg_info.size = strlen(buf);
408 g_mutex_lock(&msg_ipc_lock);
410 ret = send(sock_fd, &msg_info, sizeof(muse_msg_info_t), 0);
411 if (ret != sizeof(muse_msg_info_t)) {
412 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
413 LOGE("msg info [type : %s size : %d] send failed : %d [error %s %d]",
414 msg_type[msg_info.type], msg_info.size, ret, err_msg, errno);
419 if (msg_info.type == MUSE_MSG_TYPE_NORMAL) {
420 ret = send(sock_fd, buf, msg_info.size, 0);
421 if (ret != (int)msg_info.size) {
422 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
423 LOGE("[%s] send failed : %d [error %s %d]", buf, ret, err_msg, errno);
429 /* MUSE_MSG_TYPE_FDS */
430 memset(&iov, 0, sizeof(iov));
431 iov.iov_base = (void *)buf;
432 iov.iov_len = msg_info.size;
434 memset(&msg, 0, sizeof(msg));
440 msg.msg_control = data;
441 msg.msg_controllen = sizeof(data);
443 cptr = CMSG_FIRSTHDR(&msg);
445 fd_cnt = _muse_get_valid_fd_count(fds);
446 cptr->cmsg_len = CMSG_LEN(sizeof(int) * fd_cnt);
447 cptr->cmsg_level = SOL_SOCKET;
448 cptr->cmsg_type = SCM_RIGHTS;
449 fdptr = (int *)CMSG_DATA(cptr);
451 memcpy(fdptr, fds, sizeof(int) * fd_cnt);
453 /* the value of msg_controllen increases after memcpy so reassigns the original value */
454 msg.msg_controllen = cptr->cmsg_len;
457 if ((ret = sendmsg(sock_fd, &msg, 0)) == SEND_FAIL) {
458 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
459 LOGE("[%d] fail to send msg - [error %s %d]", sock_fd, err_msg, errno);
463 g_mutex_unlock(&msg_ipc_lock);
468 int muse_core_msg_recv(int sock_fd, char *msg, int msg_len)
470 muse_return_val_if_fail(msg, MM_ERROR_INVALID_ARGUMENT);
471 return muse_core_msg_recv_fd(sock_fd, msg, msg_len, NULL);
474 int muse_core_msg_recv_fd(int sock_fd, char *buf, int buf_len, int *out_fd)
478 struct cmsghdr *cptr;
481 muse_msg_info_t msg_info = {0,};
482 char data[CMSG_SPACE(sizeof(int) * MUSE_NUM_FD)];
483 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
485 muse_return_val_if_fail(buf, MM_ERROR_INVALID_ARGUMENT);
486 muse_return_val_if_fail(muse_core_fd_is_valid(sock_fd), MM_ERROR_INVALID_ARGUMENT);
488 /* get the msg type and length */
489 if (!muse_core_msg_recv_len(sock_fd, (char *)&msg_info, sizeof(muse_msg_info_t))) {
491 LOGE("[pid : %d] [fd : %d] msg info receive failed", pid, sock_fd);
492 muse_core_log_process_thread_info(pid);
496 if (msg_info.size > 0 && buf_len < msg_info.size) {
497 LOGE("stack overflow caution !! [recv buf's length (%d) must be larger than msg's length (%d)", buf_len, msg_info.size);
501 if (msg_info.marker != MUSE_MSG_HEAD) {
502 LOGE("invalid marker 0x%x", msg_info.marker);
506 if (msg_info.type == MUSE_MSG_TYPE_NORMAL) {
507 if (!muse_core_msg_recv_len(sock_fd, buf, msg_info.size)) {
508 LOGE("msg receive failed");
514 memset(&iov, 0, sizeof(iov));
515 iov.iov_base = (void *)buf;
516 iov.iov_len = msg_info.size;
518 memset(&msg, 0, sizeof(msg));
523 msg.msg_control = data;
524 msg.msg_controllen = sizeof(data);
526 if ((ret = recvmsg(sock_fd, &msg, 0)) == RECV_FAIL) {
527 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
528 LOGE("fail to receive msg [error %s %d]", err_msg, errno);
533 cptr = CMSG_FIRSTHDR(&msg);
535 memcpy(out_fd, CMSG_DATA(cptr), cptr->cmsg_len - CMSG_LEN(0));
544 char *muse_core_msg_new(int api, ...)
551 jobj = json_object_new_object();
553 muse_return_val_if_fail(jobj, NULL);
555 json_object_object_add(jobj, MSG_KEY_API, json_object_new_int(api));
558 _muse_msg_json_factory_args(jobj, ap);
561 jsonMsg = json_object_to_json_string(jobj);
562 sndMsg = g_strdup(jsonMsg);
564 if (api == API_CREATE)
565 SECURE_LOGD("%s", sndMsg);
567 json_object_put(jobj);
572 bool muse_core_msg_deserialize(const char *key, char *buf, int *parse_len,
573 muse_core_msg_parse_err_e *err, muse_core_msg_type_e m_type, void *data)
575 json_object *obj = NULL, *jobj = NULL;
578 muse_return_val_if_fail(key, false);
579 muse_return_val_if_fail(buf, false);
580 muse_return_val_if_fail(m_type >= MUSE_TYPE_INT && m_type < MUSE_TYPE_MAX, false);
581 muse_return_val_if_fail(data, false);
583 g_mutex_lock(&msg_lock);
585 jobj = _muse_msg_json_tokener_parse_len(buf, parse_len, err);
587 LOGE("jobj is NULL");
588 g_mutex_unlock(&msg_lock);
592 obj = _muse_msg_json_find_obj(jobj, key);
594 LOGE("\"%s\" key is not founded", key);
595 json_object_put(jobj);
596 g_mutex_unlock(&msg_lock);
600 ret = (bool)_muse_msg_json_get_obj_value(obj, m_type, data);
602 json_object_put(jobj);
604 g_mutex_unlock(&msg_lock);
609 void muse_core_msg_free(char *msg)
614 void *muse_core_msg_object_new(char *str, int *parse_len, muse_core_msg_parse_err_e *err)
618 muse_return_val_if_fail(str, NULL);
620 g_mutex_lock(&msg_lock);
622 jobj = (void *)_muse_msg_json_tokener_parse_len(str, parse_len, err);
624 g_mutex_unlock(&msg_lock);
629 bool muse_core_msg_object_get_value(const char *key, void *jobj, muse_core_msg_type_e m_type, void *data)
634 muse_return_val_if_fail(key, false);
635 muse_return_val_if_fail(jobj, false);
636 muse_return_val_if_fail(data, false);
637 muse_return_val_if_fail(m_type >= MUSE_TYPE_INT && m_type < MUSE_TYPE_MAX, false);
639 g_mutex_lock(&msg_lock);
641 obj = _muse_msg_json_find_obj((json_object *)jobj, key);
643 LOGE("\"%s\" key is not found", key);
644 g_mutex_unlock(&msg_lock);
648 ret = (bool)_muse_msg_json_get_obj_value(obj, m_type, data);
650 g_mutex_unlock(&msg_lock);
655 void muse_core_msg_object_free(void *jobj)
657 muse_return_if_fail(jobj);
659 g_mutex_lock(&msg_lock);
661 json_object_put((json_object *)jobj);
663 g_mutex_unlock(&msg_lock);
666 bool muse_core_msg_recv_len(int fd, char *buf, int msg_len)
670 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
672 if (!muse_core_fd_is_valid(fd) || !buf || msg_len <= 0) {
673 LOGE("invalid param : fd %d, buf %p, msg_len %d", fd, buf, msg_len);
678 recv_len = recv(fd, buf + offset, msg_len - offset, 0);
680 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
681 LOGE("[%d] recv failed [error %s %d]", fd, err_msg, errno);
683 } else if (recv_len == 0) {
684 LOGD("[%d] EOF", fd);
689 } while (offset < msg_len);
691 if (offset != msg_len) {
692 LOGE("invalid length received : try %d -> result %d", msg_len, offset);
699 void muse_core_change_time_format(int val, char *time_buf)
701 int sec, min, hour, day;
703 muse_return_if_fail(time_buf);
705 min = val / MUSE_MIN_SEC_VALUE;
706 hour = min / MUSE_HOUR_MIN_VALUE;
707 day = hour / MUSE_DAY_HOUR_VALUE;
709 sec = val % MUSE_MIN_SEC_VALUE;
710 min = min % MUSE_HOUR_MIN_VALUE;
711 hour = hour % MUSE_DAY_HOUR_VALUE;
713 snprintf(time_buf, MUSE_MSG_TIME_LEN, "%dd %dh %dm %ds", day, hour, min, sec);
716 void muse_core_dump_fd_state(int fd)
719 char time_buf[MUSE_MSG_TIME_LEN];
721 g_mutex_lock(&fd_state_lock);
722 sec = GPOINTER_TO_INT(g_hash_table_lookup(fd_state_table, GINT_TO_POINTER(fd)));
723 muse_core_change_time_format(sec, time_buf);
724 LOGI("[%d] %s", fd, time_buf);
725 g_mutex_unlock(&fd_state_lock);
728 void muse_core_update_fd_state(int fd)
732 g_mutex_lock(&fd_state_lock);
735 fd_state_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
737 muse_core_get_cur_time(&tv, NULL);
738 g_hash_table_insert(fd_state_table, GINT_TO_POINTER(fd), GINT_TO_POINTER((int)tv.tv_sec));
740 g_mutex_unlock(&fd_state_lock);
743 void muse_core_create_fd_table(void)
745 g_mutex_lock(&fd_state_lock);
747 if (fd_state_table) {
748 LOGW("fd state table [%p] is already created", fd_state_table);
752 fd_state_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
754 LOGE("fail to create new fd state table");
756 g_mutex_unlock(&fd_state_lock);
759 void muse_core_remove_all_fd_table(void)
761 g_mutex_lock(&fd_state_lock);
762 g_hash_table_remove_all(fd_state_table);
763 g_mutex_unlock(&fd_state_lock);
766 void muse_core_destroy_fd_table(void)
768 g_mutex_lock(&fd_state_lock);
769 g_hash_table_destroy(fd_state_table);
770 fd_state_table = NULL;
771 g_mutex_unlock(&fd_state_lock);
774 void muse_core_get_cur_time(struct timespec *time, char *time_buf)
776 char cur_time[MUSE_MSG_LEN];
780 muse_return_if_fail(clock_gettime(CLOCK_MONOTONIC, &tv) == 0);
786 strftime(cur_time, MUSE_MSG_LEN, STR_TIME_FORMAT, localtime_r(&(tv.tv_sec), &newtime));
787 snprintf(time_buf, MUSE_MSG_TIME_LEN, "%s.%03ld", cur_time, tv.tv_nsec);
791 void muse_core_log_process_thread_info(int pid)
793 char cmd[MUSE_MSG_LEN_MAX];
795 snprintf(cmd, sizeof(cmd), "/bin/cat /proc/%d/status | /bin/grep Threads", pid);
796 muse_core_log_cmd_info(cmd);
799 void muse_core_log_process_opened_fds(int pid)
801 char dir_path[MUSE_MSG_LEN_MAX];
802 struct dirent *de = NULL;
805 snprintf(dir_path, sizeof(dir_path), "/proc/%d/fd", pid); /* /proc/%d/fd is directory */
806 dr = opendir(dir_path);
807 muse_return_if_fail(dr);
809 LOGI("directory path : %s", dir_path);
811 while ((de = readdir(dr)) != NULL)
812 LOGW("%s\n", de->d_name);
817 void muse_core_log_process_cpu_memory(int pid)
819 char cmd[MUSE_MSG_LEN_MAX];
821 snprintf(cmd, sizeof(cmd), "/bin/ps -Lo pcpu,pmem,tid,comm -p %d", pid);
822 muse_core_log_cmd_info(cmd);
825 int muse_core_get_process_cpu_usage(int pid)
829 char cmd[MUSE_MSG_LEN_MAX];
830 char buf[MUSE_MSG_LEN_MAX];
832 snprintf(cmd, sizeof(cmd), "/bin/ps -Lo pcpu,pmem,tid,comm -p %d", pid);
834 fp = popen(cmd, "r");
837 while (fgets(buf, MUSE_MSG_LEN_MAX, fp)) {
839 cpu += atoi(g_strstrip(buf));
842 if (pclose(fp) == -1)
843 LOGE("Fail to pclose");
849 void muse_core_log_file_list(const char *path)
851 char cmd[MUSE_MSG_LEN_MAX];
853 snprintf(cmd, sizeof(cmd), "/bin/ls -alt %s", path);
854 muse_core_log_cmd_info(cmd);
857 void muse_core_remove_symlink(const char *path)
859 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
862 muse_return_if_fail(path);
864 r = realpath(path, NULL);
866 if (strncmp(r, path, strlen(path)) != 0) {
867 LOGW("symbolic link exists [%s] -> [%s]", path, r);
872 if (errno != ENOENT) {
873 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
874 LOGE("realpath failed [error %s %d]", err_msg, errno);