]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
add small wrapper functions around dlopen and friends.
authorRay Strode <rstrode@redhat.com>
Wed, 6 Jun 2007 18:13:07 +0000 (14:13 -0400)
committerRay Strode <rstrode@redhat.com>
Wed, 6 Jun 2007 18:14:37 +0000 (14:14 -0400)
create the start of a boot-splash api for managing the
splash screen.  Setup main.c to use the api (no plugin
exists yet, though, so things are pretty hosed atm)

configure.ac
src/Makefile.am
src/main.c
src/ply-boot-splash-plugin.h [new file with mode: 0644]
src/ply-boot-splash.c [new file with mode: 0644]
src/ply-boot-splash.h [new file with mode: 0644]
src/ply-utils.c
src/ply-utils.h
src/tests/Makefile.am
src/tests/ply-boot-splash-test.am [new file with mode: 0644]

index 8e0828da58af8ce71a3c4ce01db65874e37fe076..09afbf4f2e3a58f0040b38db30a3fee48d3c1d1b 100644 (file)
@@ -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)
index b2c94163b11b1ce0a50933034575521575fe5341..eda2a2b0a91bf7ddd86d3fc53adc455a887ae840 100644 (file)
@@ -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                                            \
index 9f384b270ebdb40ad3fc82168d2bbd7b15c017a8..4eaeb50e075cba21d63a09a049de9cd998b8b97d 100644 (file)
@@ -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 (file)
index 0000000..c0996b3
--- /dev/null
@@ -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 (file)
index 0000000..dce7f78
--- /dev/null
@@ -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 (file)
index 0000000..6ccdb15
--- /dev/null
@@ -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: */
index abf1d2fdd8e471207e80f788ca4432e6e71f9402..2136f4bb456305e13ec0d61c19399bde6479f3b3 100644 (file)
@@ -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: */
index 6a81a62feb9c54c4d66aa5d0928d290159a4f214..6a59deb7f48bef708b7951088260700dd857c3f8 100644 (file)
@@ -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 */
index 6fa2e10fc1d115193850fb02eeb1bd32bd479f7c..c43d0e389b176b0cfec73c05d54c058755d11af4 100644 (file)
@@ -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 (file)
index 0000000..6b5d4b6
--- /dev/null
@@ -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