support for liblash-less clients
This commit is contained in:
parent
0d7d4cead9
commit
b433cb0570
|
@ -1,6 +1,8 @@
|
|||
/* -*- Mode: C ; indent-tabs-mode: t ; tab-width: 8 ; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* LASH
|
||||
*
|
||||
* Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
* Copyright (C) 2002 Robert Ham <rah@bash.sh>
|
||||
*
|
||||
|
@ -36,6 +38,7 @@
|
|||
#include "store.h"
|
||||
#include "dbus_iface_control.h"
|
||||
#include "file.h"
|
||||
#include "procfs.h"
|
||||
|
||||
struct lash_client *
|
||||
client_new(void)
|
||||
|
@ -186,7 +189,7 @@ client_task_completed(struct lash_client *client,
|
|||
goto end;
|
||||
}
|
||||
|
||||
//lash_info("%s:%s task completed %s", project->name, client->name, was_succesful ? "successfully" : "with fail");
|
||||
lash_info("%s:%s task completed %s", project->name, client->name, was_succesful ? "successfully" : "with fail");
|
||||
|
||||
switch (client->task_type) {
|
||||
case LASH_Save_Data_Set:
|
||||
|
@ -457,4 +460,27 @@ client_find_by_name(struct list_head *client_list,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
client_fill_by_pid(
|
||||
struct lash_client * lash_client_ptr,
|
||||
unsigned long long pid)
|
||||
{
|
||||
lash_client_ptr->working_dir = procfs_get_process_cwd(pid);
|
||||
if (lash_client_ptr->working_dir == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!procfs_get_process_cmdline(pid, &lash_client_ptr->argc, &lash_client_ptr->argv))
|
||||
{
|
||||
free(lash_client_ptr->working_dir);
|
||||
lash_client_ptr->working_dir = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
lash_client_ptr->pid = pid;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/* -*- Mode: C ; indent-tabs-mode: t ; tab-width: 8 ; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* LASH
|
||||
*
|
||||
* Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
|
||||
* Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
|
||||
* Copyright (C) 2002 Robert Ham <rah@bash.sh>
|
||||
*
|
||||
|
@ -133,4 +135,9 @@ struct lash_client *
|
|||
client_find_by_name(struct list_head *client_list,
|
||||
const char *client_name);
|
||||
|
||||
bool
|
||||
client_fill_by_pid(
|
||||
struct lash_client * lash_client_ptr,
|
||||
unsigned long long pid);
|
||||
|
||||
#endif /* __LASHD_CLIENT_H__ */
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include "common/safety.h"
|
||||
#define LASH_DEBUG
|
||||
#include "common/debug.h"
|
||||
#include "common/klist.h"
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C ; indent-tabs-mode: t ; tab-width: 8 ; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* LASH
|
||||
*
|
||||
|
@ -89,6 +90,11 @@ lashd_dbus_connect(method_call_t *call)
|
|||
|
||||
client = server_add_client(sender, (pid_t) pid, class,
|
||||
(int) flags, wd, argc, argv);
|
||||
if (client == NULL)
|
||||
{
|
||||
lash_dbus_error(call, LASH_DBUS_ERROR_GENERIC, "server_add_client() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
id_str = (const char *) client->id_str;
|
||||
client_name = client->name ? client->name : "";
|
||||
|
|
|
@ -47,7 +47,7 @@ lashd_jackdbus_handler(DBusConnection *connection,
|
|||
void *data);
|
||||
|
||||
static void
|
||||
lashd_jackdbus_mgr_get_unknown_clients(lashd_jackdbus_mgr_t *mgr);
|
||||
lashd_jackdbus_mgr_create_raw_clients(lashd_jackdbus_mgr_t *mgr);
|
||||
|
||||
static bool
|
||||
lashd_jackdbus_mgr_get_client_data(jack_mgr_client_t *client);
|
||||
|
@ -253,14 +253,13 @@ lashd_jackdbus_mgr_new(void)
|
|||
}
|
||||
|
||||
INIT_LIST_HEAD(&mgr->clients);
|
||||
INIT_LIST_HEAD(&mgr->unknown_clients);
|
||||
g_jack_mgr_ptr = mgr;
|
||||
|
||||
/* Get list of unknown JACK clients */
|
||||
if (lashd_jackdbus_mgr_is_server_started())
|
||||
{
|
||||
lashd_jackdbus_mgr_get_graph(mgr);
|
||||
lashd_jackdbus_mgr_get_unknown_clients(mgr);
|
||||
lashd_jackdbus_mgr_create_raw_clients(mgr);
|
||||
}
|
||||
|
||||
return mgr;
|
||||
|
@ -340,6 +339,88 @@ lashd_jackdbus_get_client_pid(dbus_uint64_t client_id)
|
|||
return pid;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
lashd_jackdbus_on_client_appeared(
|
||||
const char * client_name,
|
||||
dbus_uint64_t client_id)
|
||||
{
|
||||
dbus_int64_t pid;
|
||||
struct lash_client * lash_client_ptr;
|
||||
project_t * project_ptr;
|
||||
jack_mgr_client_t * jack_client_ptr;
|
||||
|
||||
pid = lashd_jackdbus_get_client_pid(client_id);
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
lash_info(
|
||||
"Ignoring new JACK client '%s' with id %llu, pid %lld",
|
||||
client_name,
|
||||
(unsigned long long)client_id,
|
||||
(long long)pid);
|
||||
return;
|
||||
}
|
||||
|
||||
lash_info("New JACK client '%s' with id %llu, pid %lld",
|
||||
client_name, (unsigned long long)client_id, (long long)pid);
|
||||
|
||||
jack_client_ptr = jack_mgr_client_new();
|
||||
jack_client_ptr->name = lash_strdup(client_name);
|
||||
jack_client_ptr->jackdbus_id = client_id;
|
||||
jack_client_ptr->pid = (pid_t) pid;
|
||||
|
||||
/* Add JACK client to the active client list */
|
||||
list_add_tail(&jack_client_ptr->siblings, &g_jack_mgr_ptr->clients);
|
||||
|
||||
lash_client_ptr = server_find_client_by_pid(pid);
|
||||
if (lash_client_ptr == NULL)
|
||||
{
|
||||
lash_client_ptr = server_find_lost_client_by_pid(pid);
|
||||
if (lash_client_ptr != NULL)
|
||||
{
|
||||
lash_client_ptr->flags |= LASH_Restored;
|
||||
client_resume_project(lash_client_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (lash_client_ptr == NULL)
|
||||
{
|
||||
/* None of the known LASH clients have the same PID */
|
||||
/* create new raw (liblash-less) client object */
|
||||
|
||||
lash_client_ptr = client_new();
|
||||
|
||||
if (!client_fill_by_pid(lash_client_ptr, pid))
|
||||
{
|
||||
client_destroy(lash_client_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
lash_strset(&lash_client_ptr->class, client_name);
|
||||
|
||||
project_ptr = server_get_newborn_project();
|
||||
project_new_client(project_ptr, lash_client_ptr);
|
||||
|
||||
lash_debug("New raw client of project '%s' for JACK client '%s'", project_ptr->name, client_name);
|
||||
}
|
||||
|
||||
/* Copy UUID and move JACK patches from LASH client to JACK client */
|
||||
uuid_copy(jack_client_ptr->id, lash_client_ptr->id);
|
||||
jack_mgr_client_free_patch_list(&jack_client_ptr->old_patches);
|
||||
INIT_LIST_HEAD(&jack_client_ptr->old_patches);
|
||||
list_splice_init(&lash_client_ptr->jack_patches, &jack_client_ptr->old_patches);
|
||||
jack_mgr_client_dup_patch_list(&jack_client_ptr->old_patches, &jack_client_ptr->backup_patches);
|
||||
|
||||
/* Extract JACK client's data from latest graph */
|
||||
lashd_jackdbus_mgr_get_graph(g_jack_mgr_ptr);
|
||||
if (!lashd_jackdbus_mgr_get_client_data(jack_client_ptr))
|
||||
lash_error("Problem extracting client data from graph");
|
||||
|
||||
/* Copy JACK client name to LASH client, make sure it has a class string */
|
||||
lash_strset(&lash_client_ptr->jack_client_name, jack_client_ptr->name);
|
||||
}
|
||||
|
||||
/** Fill @a mgr 's unknown_clients list with one @a jack_mgr_client_t object per
|
||||
* each currently running JACK client. This is done in @a lashd_jackdbus_mgr_new
|
||||
* for @a mgr to be able to later on match JACK client PIDs against LASH clients.
|
||||
|
@ -348,15 +429,13 @@ lashd_jackdbus_get_client_pid(dbus_uint64_t client_id)
|
|||
* @param mgr Pointer to JACK D-Bus manager.
|
||||
*/
|
||||
static void
|
||||
lashd_jackdbus_mgr_get_unknown_clients(lashd_jackdbus_mgr_t *mgr)
|
||||
lashd_jackdbus_mgr_create_raw_clients(lashd_jackdbus_mgr_t *mgr)
|
||||
{
|
||||
lash_debug("Getting unknown JACK clients from graph");
|
||||
lash_debug("Creating raw clients from JACK graph");
|
||||
|
||||
DBusMessageIter iter, array_iter, struct_iter;
|
||||
dbus_uint64_t client_id;
|
||||
const char *client_name;
|
||||
dbus_int64_t pid;
|
||||
jack_mgr_client_t *jack_client;
|
||||
|
||||
if (!mgr->graph) {
|
||||
lash_error("Cannot find graph");
|
||||
|
@ -389,18 +468,7 @@ lashd_jackdbus_mgr_get_unknown_clients(lashd_jackdbus_mgr_t *mgr)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
pid = lashd_jackdbus_get_client_pid(client_id);
|
||||
if (pid != 0)
|
||||
{
|
||||
/* Create JACK client and store in mgr->unknown_clients */
|
||||
jack_client = jack_mgr_client_new();
|
||||
jack_client->name = lash_strdup(client_name);
|
||||
jack_client->jackdbus_id = client_id;
|
||||
jack_client->pid = (pid_t)pid;
|
||||
lash_debug("Storing unknown JACK client '%s'", client_name);
|
||||
list_add_tail(&jack_client->siblings, &mgr->unknown_clients);
|
||||
}
|
||||
|
||||
lashd_jackdbus_on_client_appeared(client_name, client_id);
|
||||
dbus_message_iter_next(&array_iter);
|
||||
}
|
||||
|
||||
|
@ -419,7 +487,7 @@ lashd_jackdbus_mgr_clear(
|
|||
struct list_head * node;
|
||||
struct list_head * next;
|
||||
|
||||
list_for_each_safe (node, next, &g_jack_mgr_ptr->unknown_clients)
|
||||
list_for_each_safe (node, next, &g_jack_mgr_ptr->clients)
|
||||
{
|
||||
jack_mgr_client_destroy(list_entry(node, jack_mgr_client_t, siblings));
|
||||
}
|
||||
|
@ -432,44 +500,12 @@ lashd_jackdbus_mgr_destroy(lashd_jackdbus_mgr_t *mgr)
|
|||
{
|
||||
if (mgr)
|
||||
{
|
||||
// TODO: destroy mgr->clients
|
||||
lashd_jackdbus_mgr_clear();
|
||||
free(mgr);
|
||||
g_jack_mgr_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lashd_jackdbus_mgr_bind_client(
|
||||
jack_mgr_client_t * jack_client_ptr,
|
||||
struct lash_client * lash_client_ptr)
|
||||
{
|
||||
lash_debug("Associating previously unknown JACK client '%s' with '%s'",
|
||||
jack_client_ptr->name, lash_client_ptr->name);
|
||||
|
||||
/* Unlink JACK client from its current list, if any */
|
||||
list_del(&jack_client_ptr->siblings);
|
||||
|
||||
/* Copy UUID and move JACK patches from LASH client to JACK client */
|
||||
uuid_copy(jack_client_ptr->id, lash_client_ptr->id);
|
||||
jack_mgr_client_free_patch_list(&jack_client_ptr->old_patches);
|
||||
INIT_LIST_HEAD(&jack_client_ptr->old_patches);
|
||||
list_splice_init(&lash_client_ptr->jack_patches, &jack_client_ptr->old_patches);
|
||||
jack_mgr_client_dup_patch_list(&jack_client_ptr->old_patches, &jack_client_ptr->backup_patches);
|
||||
|
||||
/* Add JACK client to the active client list */
|
||||
list_add_tail(&jack_client_ptr->siblings, &g_jack_mgr_ptr->clients);
|
||||
|
||||
/* Extract JACK client's data from latest graph */
|
||||
lashd_jackdbus_mgr_get_graph(g_jack_mgr_ptr);
|
||||
if (!lashd_jackdbus_mgr_get_client_data(jack_client_ptr))
|
||||
lash_error("Problem extracting client data from graph");
|
||||
|
||||
/* Copy JACK client name to LASH client, make sure it has a class string */
|
||||
lash_strset(&lash_client_ptr->jack_client_name, jack_client_ptr->name);
|
||||
client_maybe_fill_class(lash_client_ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
lashd_jackdbus_connect_return_handler(DBusPendingCall *pending,
|
||||
void *data)
|
||||
|
@ -500,6 +536,15 @@ lashd_jackdbus_mgr_connect_ports(const char *client1_name,
|
|||
lash_info("Attempting to resume patch '%s:%s' -> '%s:%s'",
|
||||
client1_name, port1_name, client2_name, port2_name);
|
||||
|
||||
if (!client1_name[0] ||
|
||||
!client2_name[0] ||
|
||||
!port1_name[0] ||
|
||||
!port2_name[0])
|
||||
{
|
||||
lash_error("Ignoring patch '%s:%s' -> '%s:%s'", client1_name, port1_name, client2_name, port2_name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send a port connect request */
|
||||
method_call_new_valist(g_server->dbus_service,
|
||||
NULL,
|
||||
|
@ -520,57 +565,37 @@ lashd_jackdbus_mgr_connect_ports(const char *client1_name,
|
|||
DBUS_TYPE_INVALID);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
lashd_jackdbus_on_client_appeared(
|
||||
const char * client_name,
|
||||
dbus_uint64_t client_id)
|
||||
{
|
||||
dbus_int64_t pid;
|
||||
struct lash_client * client_ptr;
|
||||
jack_mgr_client_t * jack_client_ptr;
|
||||
|
||||
pid = lashd_jackdbus_get_client_pid(client_id);
|
||||
|
||||
lash_debug("New JACK client '%s' with id %llu, pid %lld",
|
||||
client_name, (unsigned long long)client_id, (long long)pid);
|
||||
|
||||
jack_client_ptr = jack_mgr_client_new();
|
||||
jack_client_ptr->name = lash_strdup(client_name);
|
||||
jack_client_ptr->jackdbus_id = client_id;
|
||||
jack_client_ptr->pid = (pid_t) pid;
|
||||
|
||||
if (!(client_ptr = server_find_client_by_pid(pid))
|
||||
&& !(client_ptr = server_find_lost_client_by_pid(pid))) {
|
||||
/* None of the known LASH clients have the same PID */
|
||||
lash_debug("Storing unknown JACK client '%s'", client_name);
|
||||
list_add_tail(&jack_client_ptr->siblings, &g_jack_mgr_ptr->unknown_clients);
|
||||
/* TODO: we need to create liblash-less client object here */
|
||||
return;
|
||||
}
|
||||
|
||||
/* The new JACK client's PID matches a known LASH client, associate them */
|
||||
|
||||
INIT_LIST_HEAD(&jack_client_ptr->siblings);
|
||||
lashd_jackdbus_mgr_bind_client(jack_client_ptr, client_ptr);
|
||||
|
||||
lash_debug("Client added");
|
||||
}
|
||||
|
||||
/** Remove the unknown client whose id parameter matches \a client_id.
|
||||
* @param client_id The disappeared client's JACK D-Bus ID.
|
||||
*/
|
||||
static void
|
||||
lashd_jackdbus_on_client_disappeared(dbus_uint64_t client_id)
|
||||
{
|
||||
jack_mgr_client_t *client;
|
||||
jack_mgr_client_t * jack_client_ptr;
|
||||
struct lash_client * lash_client_ptr;
|
||||
|
||||
if (!(client = jack_mgr_client_find_by_jackdbus_id(&g_jack_mgr_ptr->unknown_clients, client_id)))
|
||||
jack_client_ptr = jack_mgr_client_find_by_jackdbus_id(&g_jack_mgr_ptr->clients, client_id);
|
||||
if (jack_client_ptr == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lash_debug("Removing unknown JACK client '%s'", client->name);
|
||||
list_del(&client->siblings);
|
||||
jack_mgr_client_destroy(client);
|
||||
lash_client_ptr = server_find_client_by_id(jack_client_ptr->id);
|
||||
if (lash_client_ptr != NULL &&
|
||||
lash_client_ptr->dbus_name == NULL)
|
||||
{
|
||||
client_disconnected(lash_client_ptr);
|
||||
lash_debug(
|
||||
"Closing raw client '%s' of project '%s' because JACK client '%s' disappeared",
|
||||
lash_client_ptr->name,
|
||||
lash_client_ptr->project->name,
|
||||
jack_client_ptr->name);
|
||||
return;
|
||||
}
|
||||
|
||||
lash_debug("Removing JACK client '%s'", jack_client_ptr->name);
|
||||
list_del(&jack_client_ptr->siblings);
|
||||
jack_mgr_client_destroy(jack_client_ptr);
|
||||
}
|
||||
|
||||
/** Search all known JACK clients for old patches that involve the foreign port
|
||||
|
@ -918,7 +943,7 @@ lashd_jackdbus_handle_control_signal(
|
|||
lash_info("JACK server start detected.");
|
||||
g_jack_mgr_ptr->graph_version = 0;
|
||||
lashd_jackdbus_mgr_get_graph(g_jack_mgr_ptr);
|
||||
lashd_jackdbus_mgr_get_unknown_clients(g_jack_mgr_ptr);
|
||||
lashd_jackdbus_mgr_create_raw_clients(g_jack_mgr_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C ; indent-tabs-mode: t ; tab-width: 8 ; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* LASH
|
||||
*
|
||||
|
@ -32,7 +33,6 @@
|
|||
struct _lashd_jackdbus_mgr
|
||||
{
|
||||
struct list_head clients;
|
||||
struct list_head unknown_clients; /**< List of JACK clients not known to be LASH clients. */
|
||||
DBusMessage *graph;
|
||||
dbus_uint64_t graph_version;
|
||||
};
|
||||
|
@ -48,16 +48,6 @@ lashd_jackdbus_mgr_remove_client(lashd_jackdbus_mgr_t *mgr,
|
|||
uuid_t id,
|
||||
struct list_head *backup_patches);
|
||||
|
||||
/** Bind (associate) an unknown JACK client with a known LASH client.
|
||||
* After this function has executed the JACK client pointed to by \a client
|
||||
* will be treated as belonging to the LASH client pointed to by \a lash_client.
|
||||
* @param client Pointer to JACK client to associate with \a lash_client.
|
||||
* @param lash_client Pointer to LASH client to associate with \a client.
|
||||
*/
|
||||
void
|
||||
lashd_jackdbus_mgr_bind_client(jack_mgr_client_t *client,
|
||||
struct lash_client *lash_client);
|
||||
|
||||
/** Find client with UUID @a id in jackdbus manager @a mgr and append its
|
||||
* patches to @a list. \a list must be properly initialized before calling.
|
||||
* If the operation fails the contents of \a list is undefined.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C ; indent-tabs-mode: t ; tab-width: 8 ; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* LASH
|
||||
*
|
||||
|
@ -271,6 +272,13 @@ loader_exec_program(struct lash_client *client,
|
|||
lash_debug("Running command: %s", buf);
|
||||
#endif
|
||||
|
||||
char pidstr[100];
|
||||
sprintf(pidstr, "%lld", (long long)getpid());
|
||||
if (setenv("JACK_CLIENT_PID_OVERRIDE", pidstr, true) != 0)
|
||||
{
|
||||
lash_error("setenv() failed.");
|
||||
}
|
||||
|
||||
if (run_in_terminal)
|
||||
loader_exec_program_in_xterm(client->argv);
|
||||
|
||||
|
|
150
lashd/procfs.c
150
lashd/procfs.c
|
@ -19,61 +19,99 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "procfs.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
static char g_buffer[4096];
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
static char g_buffer[BUFFER_SIZE];
|
||||
|
||||
static
|
||||
char *
|
||||
bool
|
||||
procfs_get_process_file(
|
||||
unsigned long long pid,
|
||||
const char * filename)
|
||||
const char * filename,
|
||||
char ** buffer_ptr_ptr,
|
||||
size_t * size_ptr)
|
||||
{
|
||||
int fd;
|
||||
ssize_t ret;
|
||||
size_t max;
|
||||
char * buffer_ptr;
|
||||
char * read_ptr;
|
||||
size_t buffer_size;
|
||||
size_t used_size;
|
||||
|
||||
sprintf(g_buffer, "/proc/%llu/%s", pid, filename);
|
||||
|
||||
fd = open(g_buffer, O_RDONLY);
|
||||
if (fd == -1)
|
||||
{
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer_ptr = g_buffer;
|
||||
do
|
||||
buffer_size = BUFFER_SIZE;
|
||||
buffer_ptr = malloc(buffer_size);
|
||||
if (buffer_ptr == NULL)
|
||||
{
|
||||
max = sizeof(g_buffer) - (buffer_ptr - g_buffer);
|
||||
ret = read(fd, buffer_ptr, max);
|
||||
buffer_ptr += ret;
|
||||
lash_error("malloc failed to allocate buffer with size %zu", buffer_size);
|
||||
return false;
|
||||
}
|
||||
while (ret > 0);
|
||||
|
||||
if (ret == 0)
|
||||
used_size = 0;
|
||||
read_ptr = buffer_ptr;
|
||||
loop:
|
||||
max = buffer_size - used_size;
|
||||
if (max < BUFFER_SIZE / 4)
|
||||
{
|
||||
buffer_ptr = strdup(g_buffer);
|
||||
lash_debug("process %llu %s is \"%s\"", pid, filename, buffer_ptr);
|
||||
buffer_size = used_size + BUFFER_SIZE;
|
||||
read_ptr = realloc(buffer_ptr, buffer_size);
|
||||
if (read_ptr == NULL)
|
||||
{
|
||||
lash_error("realloc failed to allocate buffer with size %zu", buffer_size);
|
||||
free(buffer_ptr);
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
buffer_ptr = read_ptr;
|
||||
read_ptr = buffer_ptr + used_size;
|
||||
max = BUFFER_SIZE;
|
||||
}
|
||||
else
|
||||
|
||||
ret = read(fd, read_ptr, max);
|
||||
if (ret > 0)
|
||||
{
|
||||
assert(ret == -1);
|
||||
buffer_ptr = NULL;
|
||||
assert(ret <= max);
|
||||
read_ptr += ret;
|
||||
used_size += ret;
|
||||
assert(used_size <= buffer_size);
|
||||
goto loop;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
return buffer_ptr;
|
||||
if (ret < 0)
|
||||
{
|
||||
assert(ret == -1);
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
*buffer_ptr_ptr = buffer_ptr;
|
||||
*size_ptr = used_size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -112,11 +150,79 @@ procfs_get_process_link(
|
|||
return buffer_ptr;
|
||||
}
|
||||
|
||||
char *
|
||||
bool
|
||||
procfs_get_process_cmdline(
|
||||
unsigned long long pid)
|
||||
unsigned long long pid,
|
||||
int * argc_ptr,
|
||||
char *** argv_ptr)
|
||||
{
|
||||
return procfs_get_process_file(pid, "cmdline");
|
||||
char * cmdline_ptr;
|
||||
char * temp_ptr;
|
||||
size_t cmdline_size;
|
||||
int i;
|
||||
int argc;
|
||||
char ** argv;
|
||||
|
||||
if (!procfs_get_process_file(pid, "cmdline", &cmdline_ptr, &cmdline_size))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
argc = 0;
|
||||
temp_ptr = cmdline_ptr;
|
||||
|
||||
while (temp_ptr - cmdline_ptr < cmdline_size)
|
||||
{
|
||||
if (*temp_ptr == 0)
|
||||
{
|
||||
argc++;
|
||||
}
|
||||
|
||||
temp_ptr++;
|
||||
}
|
||||
|
||||
assert(*(temp_ptr - 1) == 0); /* the last nul char */
|
||||
|
||||
argv = malloc((argc + 1) * sizeof(char *));
|
||||
if (argv == NULL)
|
||||
{
|
||||
free(cmdline_ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
temp_ptr = cmdline_ptr;
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
assert(temp_ptr - cmdline_ptr < cmdline_size);
|
||||
|
||||
argv[i] = strdup(temp_ptr);
|
||||
if (argv[i] == NULL)
|
||||
{
|
||||
/* rollback */
|
||||
while (i > 0)
|
||||
{
|
||||
i--;
|
||||
free(argv[i]);
|
||||
}
|
||||
|
||||
free(argv);
|
||||
free(cmdline_ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
temp_ptr += strlen(temp_ptr) + 1;
|
||||
}
|
||||
|
||||
/* Make sure that the array is NULL terminated */
|
||||
argv[argc] = NULL;
|
||||
|
||||
*argc_ptr = argc;
|
||||
*argv_ptr = argv;
|
||||
|
||||
free(cmdline_ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char *
|
||||
|
|
|
@ -22,9 +22,11 @@
|
|||
#ifndef PROCFS_H__604D0D94_1609_4BB4_BFA7_5DC47830011A__INCLUDED
|
||||
#define PROCFS_H__604D0D94_1609_4BB4_BFA7_5DC47830011A__INCLUDED
|
||||
|
||||
char *
|
||||
bool
|
||||
procfs_get_process_cmdline(
|
||||
unsigned long long pid);
|
||||
unsigned long long pid,
|
||||
int * argc_ptr,
|
||||
char *** argv_ptr);
|
||||
|
||||
char *
|
||||
procfs_get_process_cwd(
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C ; indent-tabs-mode: t ; tab-width: 8 ; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* LASH
|
||||
*
|
||||
|
@ -1145,6 +1146,12 @@ project_unload(project_t *project)
|
|||
list_for_each_safe (node, next, &project->clients) {
|
||||
client = list_entry(node, struct lash_client, siblings);
|
||||
|
||||
if (client->dbus_name == NULL && client->pid != 0)
|
||||
{
|
||||
lash_debug("Sending SIGTERM to raw client '%s' with PID %llu", client->name, (unsigned long long)client->pid);
|
||||
kill(client->pid, SIGTERM);
|
||||
}
|
||||
|
||||
if (client->jack_client_name) {
|
||||
#ifdef HAVE_JACK_DBUS
|
||||
lashd_jackdbus_mgr_remove_client(g_server->jackdbus_mgr,
|
||||
|
@ -1260,11 +1267,14 @@ void
|
|||
project_client_task_completed(project_t *project,
|
||||
struct lash_client *client)
|
||||
{
|
||||
lash_debug("----------- client '%s' task completed", client->name);
|
||||
|
||||
/* Calculate new progress reading and send Progress signal */
|
||||
project_client_progress(project, client, 100);
|
||||
|
||||
/* If the project task is finished emit the appropriate signals */
|
||||
if (project->client_tasks_pending && (--project->client_tasks_pending) == 0) {
|
||||
lash_debug("----------- project '%s' tasks completed", project->name);
|
||||
project->task_type = 0;
|
||||
project->client_tasks_total = 0;
|
||||
project->client_tasks_progress = 0;
|
||||
|
|
|
@ -271,4 +271,7 @@ project_new_client(
|
|||
project_t *project,
|
||||
struct lash_client *client);
|
||||
|
||||
project_t *
|
||||
server_get_newborn_project();
|
||||
|
||||
#endif /* __LASHD_PROJECT_H__ */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C ; indent-tabs-mode: t ; tab-width: 8 ; c-basic-offset: 8 -*- */
|
||||
/*
|
||||
* LASH
|
||||
*
|
||||
|
@ -224,7 +225,7 @@ find_client_in_list_by_dbus_name(struct list_head *client_list,
|
|||
list_for_each (node, client_list) {
|
||||
client = list_entry(node, struct lash_client, siblings);
|
||||
|
||||
if (strcmp(client->dbus_name, dbus_name) == 0)
|
||||
if (client->dbus_name != NULL && strcmp(client->dbus_name, dbus_name) == 0)
|
||||
return client;
|
||||
}
|
||||
|
||||
|
@ -477,35 +478,53 @@ server_add_client(const char *dbus_name,
|
|||
int argc,
|
||||
char **argv)
|
||||
{
|
||||
struct lash_client *client;
|
||||
struct lash_client * client_ptr;
|
||||
|
||||
/* See if we launched this client */
|
||||
if (pid && (client = server_find_lost_client_by_pid(pid))) {
|
||||
lash_strset(&client->dbus_name, dbus_name);
|
||||
client->flags |= LASH_Restored;
|
||||
client_resume_project(client);
|
||||
/* Otherwise add a new client */
|
||||
} else {
|
||||
client = client_new();
|
||||
client->pid = pid;
|
||||
lash_strset(&client->class, class);
|
||||
client->flags = flags;
|
||||
client->argc = argc;
|
||||
client->argv = argv;
|
||||
lash_strset(&client->dbus_name, dbus_name);
|
||||
lash_strset(&client->working_dir, working_dir);
|
||||
project_new_client(server_get_newborn_project(), client);
|
||||
if (pid == 0)
|
||||
{
|
||||
lash_error("Cannot add client with PID 0");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_JACK_DBUS
|
||||
/* Try to find an unknown JACK client whose PID matches the newly
|
||||
added LASH client's, if succesful bind them together */
|
||||
jack_mgr_client_t *jack_client;
|
||||
if ((jack_client = jack_mgr_client_find_by_pid(&(g_server->jackdbus_mgr->unknown_clients), pid)))
|
||||
lashd_jackdbus_mgr_bind_client(jack_client, client);
|
||||
#endif
|
||||
/* Have we launched this client? */
|
||||
client_ptr = server_find_lost_client_by_pid(pid);
|
||||
if (client_ptr != NULL)
|
||||
{
|
||||
lash_strset(&client_ptr->dbus_name, dbus_name);
|
||||
client_ptr->flags |= LASH_Restored;
|
||||
client_resume_project(client_ptr);
|
||||
return client_ptr;
|
||||
}
|
||||
|
||||
return client;
|
||||
client_ptr = server_find_client_by_pid(pid);
|
||||
/* new real lash client? */
|
||||
if (client_ptr == NULL)
|
||||
{
|
||||
client_ptr = client_new();
|
||||
client_ptr->pid = pid;
|
||||
lash_strset(&client_ptr->class, class);
|
||||
client_ptr->flags = flags;
|
||||
client_ptr->argc = argc;
|
||||
client_ptr->argv = argv;
|
||||
lash_strset(&client_ptr->dbus_name, dbus_name);
|
||||
lash_strset(&client_ptr->working_dir, working_dir);
|
||||
project_new_client(server_get_newborn_project(), client_ptr);
|
||||
return client_ptr;
|
||||
}
|
||||
|
||||
/* raw client transformed to real lash client */
|
||||
|
||||
lash_strset(&client_ptr->class, class);
|
||||
lash_strset(&client_ptr->dbus_name, dbus_name);
|
||||
lash_strset(&client_ptr->working_dir, working_dir);
|
||||
|
||||
client_ptr->flags = flags;
|
||||
|
||||
/* TODO: replace argv with what client supplied. */
|
||||
//client->argc = argc;
|
||||
//client->argv = argv;
|
||||
|
||||
return client_ptr;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
Loading…
Reference in New Issue