summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--src/Makefile.am11
-rw-r--r--src/main.c43
-rw-r--r--src/ply-boot-splash-plugin.h48
-rw-r--r--src/ply-boot-splash.c249
-rw-r--r--src/ply-boot-splash.h46
-rw-r--r--src/ply-utils.c49
-rw-r--r--src/ply-utils.h9
-rw-r--r--src/tests/Makefile.am1
-rw-r--r--src/tests/ply-boot-splash-test.am17
10 files changed, 470 insertions, 5 deletions
diff --git a/configure.ac b/configure.ac
index 8e0828d..09afbf4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -32,7 +32,7 @@ AC_SUBST(IMAGE_CFLAGS)
AC_SUBST(IMAGE_LIBS)
PLYMOUTH_CFLAGS=""
-PLYMOUTH_LIBS="-lm"
+PLYMOUTH_LIBS="-lm -ldl"
AC_SUBST(PLYMOUTH_CFLAGS)
AC_SUBST(PLYMOUTH_LIBS)
diff --git a/src/Makefile.am b/src/Makefile.am
index b2c9416..eda2a2b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,11 +2,14 @@ SUBDIRS = tests
INCLUDES = -I$(top_srcdir) \
-I$(srcdir)
-plymouth_CFLAGS =
-plymouth_LDADD =
+plymouth_CFLAGS = $(PLYMOUTH_CFLAGS)
+plymouth_LDADD = $(PLYMOUTH_LIBS)
plymouth_SOURCES = \
ply-boot-server.h \
ply-boot-server.c \
+ ply-boot-splash-plugin.h \
+ ply-boot-splash.h \
+ ply-boot-splash.c \
ply-list.h \
ply-list.c \
ply-logger.h \
@@ -20,8 +23,8 @@ plymouth_SOURCES = \
ply-utils.h \
ply-utils.c \
main.c
-rhgb_client_CFLAGS =
-rhgb_client_LDADD =
+rhgb_client_CFLAGS = $(PLYMOUTH_CFLAGS)
+rhgb_client_LDADD = $(PLYMOUTH_LIBS)
rhgb_client_SOURCES = ply-utils.h \
ply-utils.c \
ply-logger.h \
diff --git a/src/main.c b/src/main.c
index 9f384b2..4eaeb50 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,6 +32,7 @@
#include <unistd.h>
#include "ply-boot-server.h"
+#include "ply-boot-splash.h"
#include "ply-event-loop.h"
#include "ply-logger.h"
#include "ply-terminal-session.h"
@@ -41,6 +42,7 @@ typedef struct
{
ply_event_loop_t *loop;
ply_boot_server_t *boot_server;
+ ply_boot_splash_t *boot_splash;
ply_terminal_session_t *session;
} state_t;
@@ -56,6 +58,8 @@ static void
on_update (state_t *state,
const char *status)
{
+ ply_boot_splash_update_status (state->boot_splash,
+ status);
}
static void
@@ -72,6 +76,7 @@ on_quit (state_t *state)
{
ply_terminal_session_close_log (state->session);
umount ("/sysroot");
+ ply_boot_splash_hide (state->boot_splash);
ply_event_loop_exit (state->loop, 0);
}
@@ -90,6 +95,7 @@ start_boot_server (state_t *state)
ply_save_errno ();
ply_boot_server_free (server);
ply_restore_errno ();
+ return NULL;
}
ply_boot_server_attach_to_event_loop (server, state->loop);
@@ -97,6 +103,27 @@ start_boot_server (state_t *state)
return server;
}
+static ply_boot_splash_t *
+start_boot_splash (state_t *state,
+ const char *module_path)
+{
+ ply_boot_splash_t *splash;
+
+ splash = ply_boot_splash_new (module_path);
+
+ if (!ply_boot_splash_show (splash))
+ {
+ ply_save_errno ();
+ ply_boot_splash_free (splash);
+ ply_restore_errno ();
+ return NULL;
+ }
+
+ ply_boot_splash_attach_to_event_loop (splash, state->loop);
+
+ return splash;
+}
+
static ply_terminal_session_t *
spawn_session (state_t *state,
char **argv)
@@ -140,6 +167,22 @@ main (int argc,
state.loop = ply_event_loop_new ();
state.boot_server = start_boot_server (&state);
+
+ if (state.boot_server == NULL)
+ {
+ ply_error ("could not log bootup: %m");
+ return EX_UNAVAILABLE;
+ }
+
+ state.boot_splash = start_boot_splash (&state,
+ "fedora-fade-in.so");
+
+ if (state.boot_splash == NULL)
+ {
+ ply_error ("could not start boot splash: %m");
+ return EX_UNAVAILABLE;
+ }
+
state.session = spawn_session (&state, argv + 1);
if (state.session == NULL)
diff --git a/src/ply-boot-splash-plugin.h b/src/ply-boot-splash-plugin.h
new file mode 100644
index 0000000..c0996b3
--- /dev/null
+++ b/src/ply-boot-splash-plugin.h
@@ -0,0 +1,48 @@
+/* ply-boot-splash-plugin.h - plugin interface for ply_boot_splash_t
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written By: Ray Strode <rstrode@redhat.com>
+ */
+#ifndef PLY_BOOT_SPLASH_PLUGIN_H
+#define PLY_BOOT_SPLASH_PLUGIN_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "ply-event-loop.h"
+
+typedef intptr_t ply_boot_splash_plugin_t;
+
+typedef struct
+{
+ ply_boot_splash_plugin_t * (* create_plugin) (void);
+ void (* destroy_plugin) (ply_boot_splash_plugin_t *plugin);
+
+ void (* show_splash_screen) (ply_boot_splash_plugin_t *plugin);
+ void (* update_status) (ply_boot_splash_plugin_t *plugin,
+ const char *status);
+ void (* hide_splash_screen) (ply_boot_splash_plugin_t *plugin);
+ void (* attach_to_event_loop) (ply_boot_splash_plugin_t *plugin,
+ ply_event_loop_t *loop);
+
+} ply_boot_splash_plugin_interface_t;
+
+#endif /* PLY_BOOT_SPLASH_PLUGIN_H */
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
diff --git a/src/ply-boot-splash.c b/src/ply-boot-splash.c
new file mode 100644
index 0000000..dce7f78
--- /dev/null
+++ b/src/ply-boot-splash.c
@@ -0,0 +1,249 @@
+/* ply-boot-splash.h - APIs for putting up a splash screen
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written by: Ray Strode <rstrode@redhat.com>
+ */
+#include "config.h"
+#include "ply-boot-splash.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "ply-boot-splash-plugin.h"
+#include "ply-event-loop.h"
+#include "ply-list.h"
+#include "ply-logger.h"
+#include "ply-utils.h"
+
+struct _ply_boot_splash
+{
+ ply_event_loop_t *loop;
+ ply_module_handle_t *module_handle;
+ const ply_boot_splash_plugin_interface_t *plugin_interface;
+ ply_boot_splash_plugin_t *plugin;
+
+ char *module_name;
+ char *status;
+
+ uint32_t is_shown : 1;
+};
+
+typedef const ply_boot_splash_plugin_interface_t *
+ (* get_plugin_interface_function_t) (void);
+
+ply_boot_splash_t *
+ply_boot_splash_new (const char *module_name)
+{
+ ply_boot_splash_t *splash;
+
+ assert (module_name != NULL);
+
+ splash = calloc (1, sizeof (ply_boot_splash_t));
+ splash->loop = NULL;
+ splash->module_name = strdup (module_name);
+ splash->module_handle = NULL;
+ splash->is_shown = false;
+
+ return splash;
+}
+
+void
+ply_boot_splash_free (ply_boot_splash_t *splash)
+{
+ if (splash == NULL)
+ return;
+
+ if (splash->is_shown)
+ ply_boot_splash_hide (splash);
+
+ free (splash->module_name);
+ free (splash);
+}
+
+static bool
+ply_boot_splash_load_plugin (ply_boot_splash_t *splash)
+{
+ assert (splash != NULL);
+ assert (splash->module_name != NULL);
+
+ get_plugin_interface_function_t get_boot_splash_plugin_interface;
+
+ splash->module_handle = ply_open_module (splash->module_name);
+
+ if (splash->module_handle == NULL)
+ return false;
+
+ get_boot_splash_plugin_interface = (get_plugin_interface_function_t)
+ ply_module_look_up_function (splash->module_handle,
+ "ply_boot_splash_plugin_get_interface");
+
+ if (get_boot_splash_plugin_interface == NULL)
+ {
+ ply_close_module (splash->module_handle);
+ splash->module_handle = NULL;
+ return false;
+ }
+
+ splash->plugin_interface = get_boot_splash_plugin_interface ();
+
+ if (splash->plugin_interface == NULL)
+ {
+ ply_close_module (splash->module_handle);
+ splash->module_handle = NULL;
+ return false;
+ }
+
+ splash->plugin = splash->plugin_interface->create_plugin ();
+
+ assert (splash->plugin != NULL);
+
+ return true;
+}
+
+static void
+ply_boot_splash_unload_plugin (ply_boot_splash_t *splash)
+{
+ assert (splash != NULL);
+ assert (splash->plugin != NULL);
+ assert (splash->plugin_interface != NULL);
+ assert (splash->module_handle != NULL);
+
+ splash->plugin_interface->destroy_plugin (splash->plugin);
+ splash->plugin = NULL;
+
+ ply_close_module (splash->module_handle);
+ splash->plugin_interface = NULL;
+ splash->module_handle = NULL;
+}
+
+bool
+ply_boot_splash_show (ply_boot_splash_t *splash)
+{
+ assert (splash != NULL);
+ assert (splash->module_name != NULL);
+ assert (splash->loop != NULL);
+
+ if (!ply_boot_splash_load_plugin (splash))
+ return false;
+
+ assert (splash->plugin_interface != NULL);
+ assert (splash->plugin != NULL);
+ assert (splash->plugin_interface->attach_to_event_loop != NULL);
+ assert (splash->plugin_interface->show_splash_screen != NULL);
+
+ splash->plugin_interface->attach_to_event_loop (splash->plugin,
+ splash->loop);
+ splash->plugin_interface->show_splash_screen (splash->plugin);
+
+ splash->is_shown = true;
+ return true;
+}
+
+void
+ply_boot_splash_update_status (ply_boot_splash_t *splash,
+ const char *status)
+{
+ assert (splash != NULL);
+ assert (status != NULL);
+ assert (splash->plugin_interface != NULL);
+ assert (splash->plugin != NULL);
+ assert (splash->plugin_interface->update_status != NULL);
+ assert (splash->is_shown);
+
+ splash->plugin_interface->update_status (splash->plugin, status);
+}
+
+void
+ply_boot_splash_hide (ply_boot_splash_t *splash)
+{
+ assert (splash != NULL);
+ assert (splash->plugin_interface != NULL);
+ assert (splash->plugin != NULL);
+ assert (splash->plugin_interface->hide_splash_screen != NULL);
+
+ splash->plugin_interface->hide_splash_screen (splash->plugin);
+
+ ply_boot_splash_unload_plugin (splash);
+ splash->is_shown = false;
+}
+
+static void
+ply_boot_splash_detach_from_event_loop (ply_boot_splash_t *splash)
+{
+ assert (splash != NULL);
+ splash->loop = NULL;
+}
+
+void
+ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash,
+ ply_event_loop_t *loop)
+{
+ assert (splash != NULL);
+ assert (loop != NULL);
+ assert (splash->loop == NULL);
+
+ splash->loop = loop;
+
+ ply_event_loop_watch_for_exit (loop, (ply_event_loop_exit_handler_t)
+ ply_boot_splash_detach_from_event_loop,
+ splash);
+}
+
+#ifdef PLY_BOOT_SPLASH_ENABLE_TEST
+
+#include <stdio.h>
+
+#include "ply-event-loop.h"
+#include "ply-boot-splash.h"
+
+int
+main (int argc,
+ char **argv)
+{
+ ply_event_loop_t *loop;
+ ply_boot_splash_t *splash;
+ int exit_code;
+
+ exit_code = 0;
+
+ loop = ply_event_loop_new ();
+
+ splash = ply_boot_splash_new ("fedora-fade-in.so");
+ ply_boot_splash_attach_to_event_loop (splash, loop);
+
+ if (!ply_boot_splash_show (splash))
+ {
+ perror ("could not start boot status daemon");
+ return errno;
+ }
+
+ exit_code = ply_event_loop_run (loop);
+ ply_boot_splash_free (splash);
+
+ return exit_code;
+}
+
+#endif /* PLY_BOOT_SPLASH_ENABLE_TEST */
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
diff --git a/src/ply-boot-splash.h b/src/ply-boot-splash.h
new file mode 100644
index 0000000..6ccdb15
--- /dev/null
+++ b/src/ply-boot-splash.h
@@ -0,0 +1,46 @@
+/* ply-boot-splash.h - APIs for putting up a splash screen
+ *
+ * Copyright (C) 2007 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Written By: Ray Strode <rstrode@redhat.com>
+ */
+#ifndef PLY_BOOT_SPLASH_H
+#define PLY_BOOT_SPLASH_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include "ply-event-loop.h"
+
+typedef struct _ply_boot_splash ply_boot_splash_t;
+
+#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
+ply_boot_splash_t *ply_boot_splash_new (const char *module_name);
+void ply_boot_splash_free (ply_boot_splash_t *splash);
+bool ply_boot_splash_show (ply_boot_splash_t *splash);
+void ply_boot_splash_update_status (ply_boot_splash_t *splash,
+ const char *status);
+void ply_boot_splash_hide (ply_boot_splash_t *splash);
+void ply_boot_splash_attach_to_event_loop (ply_boot_splash_t *splash,
+ ply_event_loop_t *loop);
+
+#endif
+
+#endif /* PLY_BOOT_SPLASH_H */
+/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
diff --git a/src/ply-utils.c b/src/ply-utils.c
index abf1d2f..2136f4b 100644
--- a/src/ply-utils.c
+++ b/src/ply-utils.c
@@ -37,6 +37,8 @@
#include <sys/types.h>
#include <sys/un.h>
+#include <dlfcn.h>
+
#ifndef PLY_OPEN_FILE_DESCRIPTORS_DIR
#define PLY_OPEN_FILE_DESCRIPTORS_DIR "/proc/self/fd"
#endif
@@ -577,4 +579,51 @@ ply_file_system_is_mounted (const char *type,
return true;
}
+ply_module_handle_t *
+ply_open_module (const char *module_path)
+{
+ ply_module_handle_t *handle;
+
+ assert (module_path != NULL);
+
+ handle = (ply_module_handle_t *) dlopen (module_path, RTLD_NOW | RTLD_LOCAL);
+
+ if (handle == NULL)
+ {
+ dlerror ();
+ if (errno == 0)
+ errno = ELIBACC;
+ }
+
+ return handle;
+}
+
+ply_module_function_t
+ply_module_look_up_function (ply_module_handle_t *handle,
+ const char *function_name)
+{
+ ply_module_function_t function;
+
+ assert (handle != NULL);
+ assert (function_name != NULL);
+
+ dlerror ();
+ function = (ply_module_function_t) dlsym (handle, function_name);
+
+ if (dlerror () == NULL)
+ {
+ if (errno == 0)
+ errno = ELIBACC;
+
+ return NULL;
+ }
+
+ return function;
+}
+
+void
+ply_close_module (ply_module_handle_t *handle)
+{
+ dlclose (handle);
+}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
diff --git a/src/ply-utils.h b/src/ply-utils.h
index 6a81a62..6a59deb 100644
--- a/src/ply-utils.h
+++ b/src/ply-utils.h
@@ -38,6 +38,9 @@
#define CLAMP(a,b,c) (MIN (MAX ((a), (b)), (c)))
#endif
+typedef intptr_t ply_module_handle_t;
+typedef void (* ply_module_function_t) (void);
+
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
bool ply_open_unidirectional_pipe (int *sender_fd,
int *receiver_fd);
@@ -68,6 +71,12 @@ bool ply_directory_exists (const char *dir);
bool ply_file_exists (const char *file);
bool ply_file_system_is_mounted (const char *type,
const char *path);
+
+ply_module_handle_t *ply_open_module (const char *module_path);
+ply_module_function_t ply_module_look_up_function (ply_module_handle_t *handle,
+ const char *function_name);
+void ply_close_module (ply_module_handle_t *handle);
+
#endif
#endif /* PLY_UTILS_H */
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index 6fa2e10..c43d0e3 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -14,5 +14,6 @@ include $(srcdir)/ply-list-test.am
include $(srcdir)/ply-event-loop-test.am
include $(srcdir)/ply-boot-client-test.am
include $(srcdir)/ply-boot-server-test.am
+include $(srcdir)/ply-boot-splash-test.am
noinst_PROGRAMS = $(TESTS)
diff --git a/src/tests/ply-boot-splash-test.am b/src/tests/ply-boot-splash-test.am
new file mode 100644
index 0000000..6b5d4b6
--- /dev/null
+++ b/src/tests/ply-boot-splash-test.am
@@ -0,0 +1,17 @@
+TESTS += ply-boot-splash-test
+
+ply_boot_splash_test_CFLAGS = $(PLYMOUTH_CFLAGS) -DPLY_BOOT_SPLASH_ENABLE_TEST
+ply_boot_splash_test_LDADD = $(PLYMOUTH_LIBS)
+
+ply_boot_splash_test_SOURCES = \
+ $(srcdir)/../ply-utils.h \
+ $(srcdir)/../ply-utils.c \
+ $(srcdir)/../ply-logger.h \
+ $(srcdir)/../ply-logger.c \
+ $(srcdir)/../ply-list.h \
+ $(srcdir)/../ply-list.c \
+ $(srcdir)/../ply-event-loop.h \
+ $(srcdir)/../ply-event-loop.c \
+ $(srcdir)/../ply-boot-splash-plugin.h \
+ $(srcdir)/../ply-boot-splash.h \
+ $(srcdir)/../ply-boot-splash.c