daemon: find app name when client appears

This commit is contained in:
Nedko Arnaudov 2009-12-11 00:11:03 +02:00
parent bb854a8fd2
commit 5eb3930bc4
5 changed files with 137 additions and 0 deletions

View File

@ -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)

View File

@ -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 */

View File

@ -32,6 +32,7 @@
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#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;
}

View File

@ -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 */

View File

@ -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)