Back to index

dbus-test-runner  12.10.0
Classes | Defines | Functions
bustle.c File Reference
#include "dbus-test.h"

Go to the source code of this file.

Classes

struct  _DbusTestBustlePrivate

Defines

#define DBUS_TEST_BUSTLE_GET_PRIVATE(o)   (G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUS_TEST_TYPE_BUSTLE, DbusTestBustlePrivate))

Functions

static void dbus_test_bustle_class_init (DbusTestBustleClass *klass)
static void dbus_test_bustle_init (DbusTestBustle *self)
static void dbus_test_bustle_dispose (GObject *object)
static void dbus_test_bustle_finalize (GObject *object)
static void process_run (DbusTestTask *task)
static DbusTestTaskState get_state (DbusTestTask *task)
static gboolean get_passed (DbusTestTask *task)
 G_DEFINE_TYPE (DbusTestBustle, dbus_test_bustle, DBUS_TEST_TYPE_TASK)
DbusTestBustle * dbus_test_bustle_new (const gchar *filename)
void dbus_test_bustle_set_executable (DbusTestBustle *bustle, const gchar *executable)
static void bustle_watcher (GPid pid, gint status, gpointer data)
static gboolean bustle_write_error (GIOChannel *channel, GIOCondition condition, gpointer data)
static gboolean bustle_writes (GIOChannel *channel, GIOCondition condition, gpointer data)

Class Documentation

struct _DbusTestBustlePrivate

Definition at line 26 of file bustle.c.

Class Members
gboolean crashed
gchar * executable
GIOChannel * file
gchar * filename
GPid pid
GIOChannel * stderr
GIOChannel * stdout
guint watch

Define Documentation

#define DBUS_TEST_BUSTLE_GET_PRIVATE (   o)    (G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUS_TEST_TYPE_BUSTLE, DbusTestBustlePrivate))

Definition at line 39 of file bustle.c.


Function Documentation

static void bustle_watcher ( GPid  pid,
gint  status,
gpointer  data 
) [static]

Definition at line 168 of file bustle.c.

{
       g_critical("Bustle Monitor exited abruptly!");
       DbusTestBustle * bustler = DBUS_TEST_BUSTLE(data);

       if (bustler->priv->pid != 0) {
              g_spawn_close_pid(pid);
              bustler->priv->pid = 0;
       }

       bustler->priv->crashed = TRUE;
       g_signal_emit_by_name(G_OBJECT(bustler), DBUS_TEST_TASK_SIGNAL_STATE_CHANGED, DBUS_TEST_TASK_STATE_FINISHED, NULL);

       return;
}

Here is the caller graph for this function:

static gboolean bustle_write_error ( GIOChannel *  channel,
GIOCondition  condition,
gpointer  data 
) [static]

Definition at line 185 of file bustle.c.

{
       gchar * line;
       gsize termloc;

       do {
              GIOStatus status = g_io_channel_read_line (channel, &line, NULL, &termloc, NULL);

              if (status == G_IO_STATUS_EOF) {
                     return FALSE;
              }

              if (status != G_IO_STATUS_NORMAL) {
                     continue;
              }

              line[termloc] = '\0';

              dbus_test_task_print(DBUS_TEST_TASK(data), line);
              g_free(line);
       } while (G_IO_IN & g_io_channel_get_buffer_condition(channel));

       return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean bustle_writes ( GIOChannel *  channel,
GIOCondition  condition,
gpointer  data 
) [static]

Definition at line 211 of file bustle.c.

{
       gchar * line;
       gsize termloc;

       GIOStatus status = g_io_channel_read_line (channel, &line, NULL, &termloc, NULL);

       if (status != G_IO_STATUS_NORMAL) {
              return FALSE;
       }

       g_io_channel_write_chars((GIOChannel *)data,
                                                  line,
                                                  termloc,
                                                  NULL,
                                                  NULL);
       g_io_channel_write_chars((GIOChannel *)data,
                                                  "\n",
                                                  1,
                                                  NULL,
                                                  NULL);

       g_free(line);

       return TRUE;
}

Here is the caller graph for this function:

static void dbus_test_bustle_class_init ( DbusTestBustleClass *  klass) [static]

Definition at line 53 of file bustle.c.

{
       GObjectClass *object_class = G_OBJECT_CLASS (klass);

       g_type_class_add_private (klass, sizeof (DbusTestBustlePrivate));

       object_class->dispose = dbus_test_bustle_dispose;
       object_class->finalize = dbus_test_bustle_finalize;

       DbusTestTaskClass * task_class = DBUS_TEST_TASK_CLASS(klass);

       task_class->run = process_run;
       task_class->get_state = get_state;
       task_class->get_passed = get_passed;

       return;
}

Here is the call graph for this function:

static void dbus_test_bustle_dispose ( GObject *  object) [static]

Definition at line 91 of file bustle.c.

{
       g_return_if_fail(DBUS_TEST_IS_BUSTLE(object));
       DbusTestBustle * bustler = DBUS_TEST_BUSTLE(object);

       if (bustler->priv->watch != 0) {
              g_source_remove(bustler->priv->watch);
              bustler->priv->watch = 0;
       }

       if (bustler->priv->pid != 0) {
              /* TODO: Send a single dbus message */

              g_spawn_close_pid(bustler->priv->pid);
       }

       if (bustler->priv->stdout != NULL) {
              g_io_channel_shutdown(bustler->priv->stdout, TRUE, NULL);
              bustler->priv->stdout = NULL;
       }

       if (bustler->priv->stderr != NULL) {
              g_io_channel_shutdown(bustler->priv->stderr, TRUE, NULL);
              bustler->priv->stderr = NULL;
       }

       if (bustler->priv->file != NULL) {
              g_io_channel_shutdown(bustler->priv->file, TRUE, NULL);
              bustler->priv->file = NULL;
       }

       G_OBJECT_CLASS (dbus_test_bustle_parent_class)->dispose (object);
       return;
}

Here is the caller graph for this function:

static void dbus_test_bustle_finalize ( GObject *  object) [static]

Definition at line 127 of file bustle.c.

{
       g_return_if_fail(DBUS_TEST_IS_BUSTLE(object));
       DbusTestBustle * bustler = DBUS_TEST_BUSTLE(object);

       g_free(bustler->priv->filename);
       g_free(bustler->priv->executable);

       G_OBJECT_CLASS (dbus_test_bustle_parent_class)->finalize (object);
       return;
}

Here is the caller graph for this function:

static void dbus_test_bustle_init ( DbusTestBustle *  self) [static]

Definition at line 72 of file bustle.c.

{
       self->priv = DBUS_TEST_BUSTLE_GET_PRIVATE(self);

       self->priv->filename = g_strconcat(g_get_current_dir(), G_DIR_SEPARATOR_S, "bustle.log", NULL);
       self->priv->executable = g_strdup("bustle-dbus-monitor");

       self->priv->watch = 0;
       self->priv->stdout = NULL;
       self->priv->stderr = NULL;
       self->priv->file = NULL;
       self->priv->pid = 0;

       self->priv->crashed = FALSE;

       return;
}
DbusTestBustle* dbus_test_bustle_new ( const gchar *  filename)

Definition at line 140 of file bustle.c.

{
       g_return_val_if_fail(filename != NULL, NULL);

       DbusTestBustle * bustler = g_object_new(DBUS_TEST_TYPE_BUSTLE,
                                               NULL);

       g_free(bustler->priv->filename);
       bustler->priv->filename = g_strdup(filename);

       dbus_test_task_set_name(DBUS_TEST_TASK(bustler), "Bustle");

       return bustler;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void dbus_test_bustle_set_executable ( DbusTestBustle *  bustle,
const gchar *  executable 
)

Definition at line 156 of file bustle.c.

{
       g_return_if_fail(DBUS_TEST_IS_BUSTLE(bustle));
       g_return_if_fail(executable != NULL);

       g_free(bustle->priv->executable);
       bustle->priv->executable = g_strdup(executable);

       return;
}

Here is the caller graph for this function:

G_DEFINE_TYPE ( DbusTestBustle  ,
dbus_test_bustle  ,
DBUS_TEST_TYPE_TASK   
)
static gboolean get_passed ( DbusTestTask *  task) [static]

Definition at line 322 of file bustle.c.

{
       g_return_val_if_fail(DBUS_TEST_IS_BUSTLE(task), FALSE);
       DbusTestBustle * bustler = DBUS_TEST_BUSTLE(task);

       if (bustler->priv->crashed) {
              return FALSE;
       } else {
              return TRUE;
       }
}

Here is the caller graph for this function:

static DbusTestTaskState get_state ( DbusTestTask *  task) [static]

Definition at line 314 of file bustle.c.

{
       /* We're always finished, but we want an error */
       g_return_val_if_fail(DBUS_TEST_IS_BUSTLE(task), DBUS_TEST_TASK_STATE_FINISHED);
       return DBUS_TEST_TASK_STATE_FINISHED;
}

Here is the caller graph for this function:

static void process_run ( DbusTestTask *  task) [static]

Definition at line 239 of file bustle.c.

{
       g_return_if_fail(DBUS_TEST_IS_BUSTLE(task));
       DbusTestBustle * bustler = DBUS_TEST_BUSTLE(task);

       if (bustler->priv->pid != 0) {
              return;
       }
       
       GError * error = NULL;

       bustler->priv->file = g_io_channel_new_file(bustler->priv->filename, "w", &error);

       if (error != NULL) {
              g_critical("Unable to open bustle file '%s': %s", bustler->priv->filename, error->message);
              g_error_free(error);

              bustler->priv->crashed = TRUE;
              g_signal_emit_by_name(G_OBJECT(bustler), DBUS_TEST_TASK_SIGNAL_STATE_CHANGED, DBUS_TEST_TASK_STATE_FINISHED, NULL);
              return;
       }

       gint bustle_stdout_num;
       gint bustle_stderr_num;
       
       gchar ** bustle_monitor = g_new0(gchar *, 3);
       bustle_monitor[0] = (gchar *)bustler->priv->executable;
       bustle_monitor[1] = "--session";

       g_spawn_async_with_pipes(g_get_current_dir(),
                                bustle_monitor, /* argv */
                                NULL, /* envp */
                                /* G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL, */ /* flags */
                                G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, /* flags */
                                NULL, /* child setup func */
                                NULL, /* child setup data */
                                &bustler->priv->pid, /* PID */
                                NULL, /* stdin */
                                &bustle_stdout_num, /* stdout */
                                &bustle_stderr_num, /* stderr */
                                &error); /* error */

       if (error != NULL) {
              g_critical("Unable to start bustling data: %s", error->message);
              g_error_free(error);

              bustler->priv->pid = 0; /* ensure this */
              bustler->priv->crashed = TRUE;
              g_signal_emit_by_name(G_OBJECT(bustler), DBUS_TEST_TASK_SIGNAL_STATE_CHANGED, DBUS_TEST_TASK_STATE_FINISHED, NULL);
              return;
       }

       if (TRUE) {
              gchar * start = g_strdup_printf("Starting bustle monitor.  PID: %d", bustler->priv->pid);
              dbus_test_task_print(DBUS_TEST_TASK(bustler), start);
              g_free(start);
       }
       bustler->priv->watch = g_child_watch_add(bustler->priv->pid, bustle_watcher, bustler);

       bustler->priv->stdout = g_io_channel_unix_new(bustle_stdout_num);
       g_io_add_watch(bustler->priv->stdout,
                      G_IO_IN | G_IO_PRI, /* conditions */
                      bustle_writes, /* func */
                      bustler->priv->file); /* func data */

       bustler->priv->stderr = g_io_channel_unix_new(bustle_stderr_num);
       g_io_add_watch(bustler->priv->stderr,
                      G_IO_IN, /* conditions */
                      bustle_write_error, /* func */
                      bustler); /* func data */

       return;
}

Here is the call graph for this function:

Here is the caller graph for this function: