diff --git a/daemon/app_supervisor.c b/daemon/app_supervisor.c index 5c2a46dd..043a77a2 100644 --- a/daemon/app_supervisor.c +++ b/daemon/app_supervisor.c @@ -395,6 +395,30 @@ void ladish_app_supervisor_stop(ladish_app_supervisor_handle supervisor_handle) } } +char * ladish_app_supervisor_search_app(ladish_app_supervisor_handle supervisor_handle, pid_t pid) +{ + struct list_head * node_ptr; + struct ladish_app * app_ptr; + char * name; + + list_for_each(node_ptr, &supervisor_ptr->applist) + { + app_ptr = list_entry(node_ptr, struct ladish_app, siblings); + if (app_ptr->pid == pid) + { + name = strdup(app_ptr->name); + if (name == NULL) + { + log_error("strdup() failed for '%s'", app_ptr->name); + } + + return name; + } + } + + return NULL; +} + #undef supervisor_ptr #define supervisor_ptr ((struct ladish_app_supervisor *)call_ptr->iface_context) diff --git a/daemon/app_supervisor.h b/daemon/app_supervisor.h index b9699d52..db7e24b8 100644 --- a/daemon/app_supervisor.h +++ b/daemon/app_supervisor.h @@ -58,4 +58,6 @@ void ladish_app_supervisor_autorun(ladish_app_supervisor_handle supervisor_handl extern const struct dbus_interface_descriptor g_iface_app_supervisor; +char * ladish_app_supervisor_search_app(ladish_app_supervisor_handle supervisor_handle, pid_t pid); + #endif /* #ifndef APP_SUPERVISOR_H__712E6589_DCB1_4CE9_9812_4F250D55E8A2__INCLUDED */ diff --git a/daemon/procfs.c b/daemon/procfs.c index 55163d07..fdd05063 100644 --- a/daemon/procfs.c +++ b/daemon/procfs.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "procfs.h" @@ -111,6 +112,18 @@ loop: return false; } + if (used_size == buffer_size) + { + buffer_ptr = realloc(buffer_ptr, buffer_size + 1); + if (buffer_ptr == NULL) + { + log_error("realloc failed to allocate buffer with size %zu", buffer_size + 1); + return false; + } + } + + buffer_ptr[buffer_size] = 0; + *buffer_ptr_ptr = buffer_ptr; *size_ptr = used_size; @@ -234,3 +247,66 @@ procfs_get_process_cwd( { return procfs_get_process_link(pid, "cwd"); } + +unsigned long long +procfs_get_process_parent( + unsigned long long pid) +{ + char * buffer_ptr; + size_t buffer_size; + char * begin; + char * end; + unsigned long long ppid; + + if (!procfs_get_process_file(pid, "status", &buffer_ptr, &buffer_size)) + { + return 0; + } + + begin = strstr(buffer_ptr, "\nPPid:\t"); + if (begin == NULL) + { + log_error("parent pid not parsed for %llu", pid); + log_error("-----------------------------"); + log_error("%s", buffer_ptr); + log_error("-----------------------------"); + return 0; + } + + begin += 7; + + end = strchr(begin, '\n'); + if (end == NULL) + { + log_error("parent pid not parsed for %llu (end)", pid); + log_error("-----------------------------"); + log_error("%s", buffer_ptr); + log_error("-----------------------------"); + return 0; + } + + *end = 0; + //log_info("parent pid is %s", begin); + + errno = 0; + ppid = strtoull(begin, &end, 10); + if (errno != 0) + { + log_error("strtoull failed to convert '%s' to integer", begin); + ppid = 0; + } + else + { + //log_info("parent pid is %llu", ppid); + } + + /* avoid infinite cycles (should not happen because init has pid 1 and parent 0) */ + if (ppid == pid) + { + ppid = 0; + } + + free(buffer_ptr); + + return ppid; +} diff --git a/daemon/procfs.h b/daemon/procfs.h index d119fe74..271619c3 100644 --- a/daemon/procfs.h +++ b/daemon/procfs.h @@ -39,4 +39,8 @@ char * procfs_get_process_cwd( unsigned long long pid); +unsigned long long +procfs_get_process_parent( + unsigned long long pid); + #endif /* #ifndef PROCFS_H__604D0D94_1609_4BB4_BFA7_5DC47830011A__INCLUDED */ diff --git a/daemon/virtualizer.c b/daemon/virtualizer.c index bb759702..d6e10b61 100644 --- a/daemon/virtualizer.c +++ b/daemon/virtualizer.c @@ -27,6 +27,9 @@ #include "virtualizer.h" #include "../dbus_constants.h" #include "a2j_proxy.h" +#include "procfs.h" +#include "app_supervisor.h" +#include "studio_internal.h" struct virtualizer { @@ -59,6 +62,8 @@ static void client_appeared(void * context, uint64_t id, const char * name) const char * a2j_name; bool is_a2j; int64_t pid; + unsigned long long ppid; + char * app_name; log_info("client_appeared(%"PRIu64", %s)", id, name); @@ -68,6 +73,27 @@ static void client_appeared(void * context, uint64_t id, const char * name) } log_info("client pid is %"PRId64, pid); + app_name = NULL; + if (pid != 0) + { + ppid = (unsigned long long)pid; + loop: + app_name = ladish_app_supervisor_search_app(g_studio.app_supervisor, ppid); + if (app_name == NULL) + { + ppid = procfs_get_process_parent(ppid); + if (ppid != 0) + { + //log_info("parent pid %llu", ppid); + goto loop; + } + } + } + + if (app_name != NULL) + { + log_info("app name is '%s'", app_name); + } a2j_name = a2j_proxy_get_jack_client_name_cached(); is_a2j = a2j_name != NULL && strcmp(a2j_name, name) == 0; @@ -110,6 +136,11 @@ exit: { virtualizer_ptr->system_client_id = id; } + + if (app_name != NULL) + { + free(app_name); + } } static void client_disappeared(void * context, uint64_t id)