raster pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=fe56edae3f5015c62e319d5e2ab2552d3533eead

commit fe56edae3f5015c62e319d5e2ab2552d3533eead
Author: Carsten Haitzler (Rasterman) <[email protected]>
Date:   Fri May 15 12:24:36 2020 +0100

    systemd - make libsystemd use/supprot entirely runtime "dlopened"
    
    so i've moved all systemd and elogind support to be runtime only with
    dlopen (eina_module) of libsystemd.so.0 (or libelogind.so.0 for elput)
    and finding of symbols manually at runtime (if the right code paths or
    env vars are set), thus remvoing the need to decide at compile time if
    efl needs systemd support or not as it no longer needs systemd
    headers/libs at compile time and just at runtime. this simplifies
    building a bit and makes efl more adaptive to the final target system
    at runtime.
---
 meson_options.txt                     |  8 +---
 src/lib/ecore/ecore.c                 | 47 +++++++++++++++++---
 src/lib/ecore/ecore_main.c            | 12 +++--
 src/lib/ecore/ecore_private.h         |  6 +++
 src/lib/ecore/meson.build             |  4 --
 src/lib/ecore_con/ecore_con.c         | 67 ++++++++++++++++++++++++----
 src/lib/ecore_con/ecore_con_local.c   |  4 --
 src/lib/ecore_con/ecore_con_private.h |  7 +++
 src/lib/ecore_con/efl_net_server_fd.c |  6 +--
 src/lib/ecore_con/meson.build         |  2 +-
 src/lib/ecore_drm/ecore_drm_logind.c  | 72 ++++++++++++++++++++++++++----
 src/lib/ecore_drm/ecore_drm_private.h |  4 --
 src/lib/eina/eina_log.c               | 79 ++++++++++++++++++++++++---------
 src/lib/eina/meson.build              |  7 ---
 src/lib/elput/elput_logind.c          | 83 +++++++++++++++++++++++++++++++----
 src/lib/elput/elput_manager.c         |  2 +-
 src/lib/elput/elput_private.h         |  8 ----
 src/lib/elput/meson.build             |  6 ---
 18 files changed, 319 insertions(+), 105 deletions(-)

diff --git a/meson_options.txt b/meson_options.txt
index 043957e046..0d07d396fc 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -128,7 +128,7 @@ option('gstreamer',
 option('systemd',
   type : 'boolean',
   value : true,
-  description : 'Systemd support in efl'
+  description : 'Systemd and Elogind support at runtime in efl'
 )
 
 option('pulseaudio',
@@ -334,12 +334,6 @@ option('native-arch-optimization',
   description: 'Enable architecture native optimizations in efl'
 )
 
-option('elogind',
-  type : 'boolean',
-  value : false,
-  description : 'elogind support in efl (subset of systemd)'
-)
-
 option('windows-version',
   type : 'combo',
   choices : ['vista', 'win7', 'win8', 'win81', 'win10'],
diff --git a/src/lib/ecore/ecore.c b/src/lib/ecore/ecore.c
index 3110c5ef54..ce5bf6e62a 100644
--- a/src/lib/ecore/ecore.c
+++ b/src/lib/ecore/ecore.c
@@ -313,9 +313,7 @@ ecore_init(void)
 #ifdef HAVE_SYSTEMD
    if (getenv("WATCHDOG_USEC"))
      {
-        double sec;
-
-        sec = ((double) atoi(getenv("WATCHDOG_USEC"))) / 1000 / 1000;
+        double sec = ((double) atoi(getenv("WATCHDOG_USEC"))) / 1000 / 1000;
 
         _systemd_watchdog =
            efl_add(EFL_LOOP_TIMER_CLASS, efl_main_loop_get(),
@@ -326,7 +324,6 @@ ecore_init(void)
         unsetenv("WATCHDOG_USEC");
 
         INF("Setup systemd watchdog to : %f", sec);
-
         _systemd_watchdog_cb(NULL, NULL);
      }
 #endif
@@ -962,7 +959,11 @@ _ecore_fps_debug_runtime_add(double t)
 static void
 _systemd_watchdog_cb(void *data EINA_UNUSED, const Efl_Event *event 
EINA_UNUSED)
 {
-   sd_notify(0, "WATCHDOG=1");
+   if (getenv("NOTIFY_SOCKET"))
+     {
+        _ecore_sd_init();
+        if (_ecore_sd_notify) _ecore_sd_notify(0, "WATCHDOG=1");
+     }
 }
 #endif
 
@@ -1122,3 +1123,39 @@ ecore_memory_state_set(Ecore_Memory_State state)
    _ecore_memory_state = state;
    ecore_event_add(ECORE_EVENT_MEMORY_STATE, NULL, NULL, NULL);
 }
+
+#ifdef HAVE_SYSTEMD
+static Eina_Module *_libsystemd = NULL;
+static Eina_Bool _libsystemd_broken = EINA_FALSE;
+
+int (*_ecore_sd_notify) (int unset_environment, const char *state) = NULL;
+
+void
+_ecore_sd_init(void)
+{
+   if (_libsystemd_broken) return;
+   _libsystemd = eina_module_new("libsystemd.so.0");
+   if (_libsystemd)
+     {
+        if (!eina_module_load(_libsystemd))
+          {
+             eina_module_free(_libsystemd);
+             _libsystemd = NULL;
+          }
+     }
+   if (!_libsystemd)
+     {
+        _libsystemd_broken = EINA_TRUE;
+        return;
+     }
+   _ecore_sd_notify =
+     eina_module_symbol_get(_libsystemd, "sd_notify");
+   if (!_ecore_sd_notify)
+     {
+        _ecore_sd_notify = NULL;
+        eina_module_free(_libsystemd);
+        _libsystemd = NULL;
+        _libsystemd_broken = EINA_TRUE;
+     }
+}
+#endif
diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index fc35331f3f..2e404a4d2d 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -20,10 +20,6 @@
 #include <fcntl.h>
 #include <sys/time.h>
 
-#ifdef HAVE_SYSTEMD
-# include <systemd/sd-daemon.h>
-#endif
-
 #ifdef HAVE_IEEEFP_H
 # include <ieeefp.h> // for Solaris
 #endif
@@ -1195,9 +1191,11 @@ _ecore_main_loop_begin(Eo *obj, Efl_Loop_Data *pd)
    pd->loop_active++;
    if (obj == ML_OBJ)
      {
-#ifdef HAVE_SYSTEMD
-        sd_notify(0, "READY=1");
-#endif
+        if (getenv("NOTIFY_SOCKET"))
+          {
+             _ecore_sd_init();
+             if (_ecore_sd_notify) _ecore_sd_notify(0, "READY=1");
+          }
 #ifdef HAVE_LIBUV
         if (!_dl_uv_run)
           {
diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h
index 8e9b796c2c..f87e5e753f 100644
--- a/src/lib/ecore/ecore_private.h
+++ b/src/lib/ecore/ecore_private.h
@@ -511,6 +511,12 @@ extern Eina_Bool _ecore_glib_always_integrate;
 extern Ecore_Select_Function main_loop_select;
 extern int in_main_loop;
 
+#ifdef HAVE_SYSTEMD
+void _ecore_sd_init(void);
+
+extern int (*_ecore_sd_notify) (int unset_environment, const char *state);
+#endif
+
 Eina_Bool ecore_mempool_init(void);
 void ecore_mempool_shutdown(void);
 #define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \
diff --git a/src/lib/ecore/meson.build b/src/lib/ecore/meson.build
index 34c32e753d..637761dcc4 100644
--- a/src/lib/ecore/meson.build
+++ b/src/lib/ecore/meson.build
@@ -192,10 +192,6 @@ if get_option('g-mainloop') == true
   endif
 endif
 
-if get_option('systemd') == true
-  ecore_deps += systemd
-endif
-
 ecore_lib = library('ecore',
     ecore_src, pub_eo_file_target,
     dependencies: ecore_pub_deps + [m, buildsystem, ecore_deps],
diff --git a/src/lib/ecore_con/ecore_con.c b/src/lib/ecore_con/ecore_con.c
index 8a4e0fb43e..dd7fc23d4b 100644
--- a/src/lib/ecore_con/ecore_con.c
+++ b/src/lib/ecore_con/ecore_con.c
@@ -34,10 +34,6 @@
 # include <sys/filio.h>
 #endif
 
-#ifdef HAVE_SYSTEMD
-# include <systemd/sd-daemon.h>
-#endif
-
 #ifdef _WIN32
 # include <ws2tcpip.h>
 # include <evil_private.h> /* evil_init|shutdown */
@@ -107,7 +103,11 @@ ecore_con_init(void)
    EFL_NET_SOCKET_SSL_ERROR_CERTIFICATE_VERIFY_FAILED;
 
 #ifdef HAVE_SYSTEMD
-   sd_fd_max = sd_listen_fds(0);
+   if (getenv("LISTEN_PID") && getenv("LISTEN_FDS"))
+     {
+        _ecore_con_sd_init();
+        if (_ecore_sd_listen_fds) sd_fd_max = _ecore_sd_listen_fds(0);
+     }
 #endif
 
    eina_log_timing(_ecore_con_log_dom,
@@ -389,11 +389,16 @@ efl_net_ip_port_split(char *buf, const char **p_host, 
const char **p_port)
 Eina_Error
 efl_net_ip_socket_activate_check(const char *address, int family, int type, 
Eina_Bool *listening)
 {
-   SOCKET fd = SD_LISTEN_FDS_START + sd_fd_index;
+   SOCKET fd = /*SD_LISTEN_FDS_START*/3 + sd_fd_index;
    int r;
 
+   // check first as this will return if we're not socket activated...
+   // or systemd not found, which means the below init will not be done then
    if (sd_fd_index >= sd_fd_max) return ENOENT;
 
+   _ecore_con_sd_init();
+   if ((!_ecore_sd_is_socket_unix) || (!_ecore_sd_is_socket)) return ENOENT;
+
    if (family == AF_UNIX)
      {
         char buf[sizeof(struct sockaddr_un)] = "";
@@ -424,7 +429,7 @@ efl_net_ip_socket_activate_check(const char *address, int 
family, int type, Eina
              len = strlen(address) + 1;
           }
 
-        r = sd_is_socket_unix(fd, type, 0, sun_path, len);
+        r = _ecore_sd_is_socket_unix(fd, type, 0, sun_path, len);
         if (r < 0)
           {
              ERR("socket " SOCKET_FMT " is not of family=%d, type=%d", fd, 
family, type);
@@ -443,7 +448,7 @@ efl_net_ip_socket_activate_check(const char *address, int 
family, int type, Eina
         Eina_Error err;
         int x;
 
-        r = sd_is_socket(fd, family, type, (type == SOCK_DGRAM) ? -1 : 0);
+        r = _ecore_sd_is_socket(fd, family, type, (type == SOCK_DGRAM) ? -1 : 
0);
         if (r < 0)
           {
              ERR("socket " SOCKET_FMT " is not of family=%d, type=%d", fd, 
family, type);
@@ -2588,3 +2593,49 @@ ecore_con_libproxy_proxies_free(char **proxies)
      free(*itr);
    free(proxies);
 }
+
+#ifdef HAVE_SYSTEMD
+static Eina_Module *_libsystemd = NULL;
+static Eina_Bool _libsystemd_broken = EINA_FALSE;
+
+int (*_ecore_sd_listen_fds) (int unset_environment) = NULL;
+int (*_ecore_sd_is_socket_unix) (int fd, int type, int listening, const char 
*path, size_t length) = NULL;
+int (*_ecore_sd_is_socket) (int fd, int family, int type, int listening) = 
NULL;
+
+void
+_ecore_con_sd_init(void)
+{
+   if (_libsystemd_broken) return;
+   _libsystemd = eina_module_new("libsystemd.so.0");
+   if (_libsystemd)
+     {
+        if (!eina_module_load(_libsystemd))
+          {
+             eina_module_free(_libsystemd);
+             _libsystemd = NULL;
+          }
+     }
+   if (!_libsystemd)
+     {
+        _libsystemd_broken = EINA_TRUE;
+        return;
+     }
+   _ecore_sd_listen_fds =
+     eina_module_symbol_get(_libsystemd, "sd_listen_fds");
+   _ecore_sd_is_socket_unix =
+     eina_module_symbol_get(_libsystemd, "sd_is_socket_unix");
+   _ecore_sd_is_socket =
+     eina_module_symbol_get(_libsystemd, "sd_is_socket");
+   if ((!_ecore_sd_listen_fds) ||
+       (!_ecore_sd_is_socket_unix) ||
+       (!_ecore_sd_is_socket))
+     {
+        _ecore_sd_listen_fds = NULL;
+        _ecore_sd_is_socket_unix = NULL;
+        _ecore_sd_is_socket = NULL;
+        eina_module_free(_libsystemd);
+        _libsystemd = NULL;
+        _libsystemd_broken = EINA_TRUE;
+     }
+}
+#endif
diff --git a/src/lib/ecore_con/ecore_con_local.c 
b/src/lib/ecore_con/ecore_con_local.c
index fae182e133..993487880a 100644
--- a/src/lib/ecore_con/ecore_con_local.c
+++ b/src/lib/ecore_con/ecore_con_local.c
@@ -17,10 +17,6 @@
 #endif
 #include <libgen.h>
 
-#ifdef HAVE_SYSTEMD
-# include <systemd/sd-daemon.h>
-#endif
-
 #ifdef _WIN32
 # include <ws2tcpip.h>
 #endif
diff --git a/src/lib/ecore_con/ecore_con_private.h 
b/src/lib/ecore_con/ecore_con_private.h
index 7f0c95d61d..805abbecb6 100644
--- a/src/lib/ecore_con/ecore_con_private.h
+++ b/src/lib/ecore_con/ecore_con_private.h
@@ -90,6 +90,13 @@ struct Ecore_Con_Socks_v5
 #ifdef HAVE_SYSTEMD
 extern int sd_fd_index;
 extern int sd_fd_max;
+
+void _ecore_con_sd_init(void);
+
+extern int (*_ecore_sd_listen_fds) (int unset_environment);
+extern int (*_ecore_sd_is_socket_unix) (int fd, int type, int listening, const 
char *path, size_t length);
+extern int (*_ecore_sd_is_socket) (int fd, int family, int type, int 
listening);
+
 #endif
 
 /* init must be called from main thread */
diff --git a/src/lib/ecore_con/efl_net_server_fd.c 
b/src/lib/ecore_con/efl_net_server_fd.c
index d3d61ca46f..62fef94eed 100644
--- a/src/lib/ecore_con/efl_net_server_fd.c
+++ b/src/lib/ecore_con/efl_net_server_fd.c
@@ -14,10 +14,6 @@
 # include <sys/socket.h>
 #endif
 
-#ifdef HAVE_SYSTEMD
-# include <systemd/sd-daemon.h>
-#endif
-
 #define MY_CLASS EFL_NET_SERVER_FD_CLASS
 
 typedef struct _Efl_Net_Server_Fd_Data
@@ -233,7 +229,7 @@ _efl_net_server_fd_socket_activate(Eo *o, 
Efl_Net_Server_Fd_Data *pd EINA_UNUSED
      }
    else
      {
-        SOCKET fd = SD_LISTEN_FDS_START + sd_fd_index;
+        SOCKET fd = /*SD_LISTEN_FDS_START*/3 + sd_fd_index;
         int family;
         socklen_t len = sizeof(family);
 
diff --git a/src/lib/ecore_con/meson.build b/src/lib/ecore_con/meson.build
index fc53d3210f..44faa486af 100644
--- a/src/lib/ecore_con/meson.build
+++ b/src/lib/ecore_con/meson.build
@@ -184,7 +184,7 @@ ecore_con_deps += crypto
 
 ecore_con_lib = library('ecore_con',
     ecore_con_src, pub_eo_file_target,
-    dependencies: [ecore, ecore_con_deps, http_parser, eldbus, eet, systemd, 
buildsystem, dl],
+    dependencies: [ecore, ecore_con_deps, http_parser, eldbus, eet, 
buildsystem, dl],
     include_directories : config_dir,
     install: true,
     c_args : package_c_args,
diff --git a/src/lib/ecore_drm/ecore_drm_logind.c 
b/src/lib/ecore_drm/ecore_drm_logind.c
index f5792a774c..4266239a84 100644
--- a/src/lib/ecore_drm/ecore_drm_logind.c
+++ b/src/lib/ecore_drm/ecore_drm_logind.c
@@ -36,12 +36,62 @@
 static Ecore_Event_Handler *active_hdlr;
 
 #ifdef HAVE_SYSTEMD
-static inline Eina_Bool 
+static Eina_Module *_libsystemd = NULL;
+static Eina_Bool _libsystemd_broken = EINA_FALSE;
+
+static int (*_ecore_sd_session_get_vt) (const char *session, unsigned *vtnr) = 
NULL;
+static int (*_ecore_sd_pid_get_session) (pid_t pid, char **session) = NULL;
+static int (*_ecore_sd_session_get_seat) (const char *session, char **seat) = 
NULL;
+
+void
+_ecore_drm_sd_init(void)
+{
+   if (_libsystemd_broken) return;
+   _libsystemd = eina_module_new("libsystemd.so.0");
+   if (_libsystemd)
+     {
+        if (!eina_module_load(_libsystemd))
+          {
+             eina_module_free(_libsystemd);
+             _libsystemd = NULL;
+          }
+     }
+   if (!_libsystemd)
+     {
+        _libsystemd_broken = EINA_TRUE;
+        return;
+     }
+   _ecore_sd_session_get_vt =
+     eina_module_symbol_get(_libsystemd, "sd_session_get_vt");
+   _ecore_sd_pid_get_session =
+     eina_module_symbol_get(_libsystemd, "sd_pid_get_session");
+   _ecore_sd_session_get_seat =
+     eina_module_symbol_get(_libsystemd, "sd_session_get_seat");
+   if ((!_ecore_sd_session_get_vt) ||
+       (!_ecore_sd_pid_get_session) ||
+       (!_ecore_sd_session_get_seat))
+     {
+        _ecore_sd_session_get_vt = NULL;
+        _ecore_sd_pid_get_session = NULL;
+        _ecore_sd_session_get_seat = NULL;
+        eina_module_free(_libsystemd);
+        _libsystemd = NULL;
+        _libsystemd_broken = EINA_TRUE;
+     }
+}
+
+static inline Eina_Bool
 _ecore_drm_logind_vt_get(Ecore_Drm_Device *dev)
 {
    int ret;
 
-   ret = sd_session_get_vt(dev->session, &dev->vt);
+   _ecore_drm_sd_init();
+   if (!_ecore_sd_session_get_vt)
+     {
+        ERR("Could not get systemd tty");
+        return EINA_FALSE;
+     }
+   ret = _ecore_sd_session_get_vt(dev->session, &dev->vt);
    if (ret < 0)
      {
         ERR("Could not get systemd tty");
@@ -142,20 +192,26 @@ _ecore_drm_logind_cb_activate(void *data, int type 
EINA_UNUSED, void *event)
    return ECORE_CALLBACK_PASS_ON;
 }
 
-Eina_Bool 
+Eina_Bool
 _ecore_drm_logind_connect(Ecore_Drm_Device *dev)
 {
 #ifdef HAVE_SYSTEMD
-   char *seat;
+   char *seat = NULL;
 
+   _ecore_drm_sd_init();
+   if ((!_ecore_sd_pid_get_session) ||
+       (!_ecore_sd_session_get_seat))
+     {
+        ERR("Could not get systemd session");
+        return EINA_FALSE;
+     }
    /* get session id */
-   if (sd_pid_get_session(getpid(), &dev->session) < 0)
+   if (_ecore_sd_pid_get_session(getpid(), &dev->session) < 0)
      {
         ERR("Could not get systemd session");
         return EINA_FALSE;
      }
-
-   if (sd_session_get_seat(dev->session, &seat) < 0)
+   if (_ecore_sd_session_get_seat(dev->session, &seat) < 0)
      {
         ERR("Could not get systemd seat");
         return EINA_FALSE;
@@ -166,9 +222,7 @@ _ecore_drm_logind_connect(Ecore_Drm_Device *dev)
         free(seat);
         return EINA_FALSE;
      }
-
    free(seat);
-
    if (!_ecore_drm_logind_vt_get(dev)) return EINA_FALSE;
 #endif
 
diff --git a/src/lib/ecore_drm/ecore_drm_private.h 
b/src/lib/ecore_drm/ecore_drm_private.h
index 5e292372fd..0be6a61ef8 100644
--- a/src/lib/ecore_drm/ecore_drm_private.h
+++ b/src/lib/ecore_drm/ecore_drm_private.h
@@ -53,10 +53,6 @@
 # include <linux/input.h>
 # include <libinput.h>
 
-# ifdef HAVE_SYSTEMD
-#  include <systemd/sd-login.h>
-# endif
-
 # include <Eldbus.h>
 # include <Ecore_Drm.h>
 
diff --git a/src/lib/eina/eina_log.c b/src/lib/eina/eina_log.c
index 7c66ee0b53..4cd634bd72 100644
--- a/src/lib/eina/eina_log.c
+++ b/src/lib/eina/eina_log.c
@@ -29,10 +29,6 @@
 #include <assert.h>
 #include <errno.h>
 
-#ifdef HAVE_SYSTEMD
-# include <systemd/sd-journal.h>
-#endif
-
 #ifdef _WIN32
 # include <windows.h>
 #endif
@@ -51,6 +47,7 @@
 #include "eina_thread.h"
 #include "eina_convert.h"
 #include "eina_strbuf.h"
+#include "eina_module.h"
 
 /* undefs EINA_ARG_NONULL() so NULL checks are not compiled out! */
 #include "eina_safety_checks.h"
@@ -2091,6 +2088,43 @@ eina_log_print_cb_stdout(const Eina_Log_Domain *d,
 #endif
 }
 
+#ifdef HAVE_SYSTEMD
+static Eina_Module *_libsystemd = NULL;
+static Eina_Bool _libsystemd_broken = EINA_FALSE;
+
+static int (*_eina_sd_journal_send_with_location) (const char *file, const 
char *line, const char *func, const char *format, ...) = NULL;
+
+static void
+_eina_sd_init(void)
+{
+   if (_libsystemd_broken) return;
+   _libsystemd = eina_module_new("libsystemd.so.0");
+   if (_libsystemd)
+     {
+        if (!eina_module_load(_libsystemd))
+          {
+             eina_module_free(_libsystemd);
+             _libsystemd = NULL;
+          }
+     }
+   if (!_libsystemd)
+     {
+        _libsystemd_broken = EINA_TRUE;
+        return;
+     }
+   _eina_sd_journal_send_with_location =
+     eina_module_symbol_get(_libsystemd, "sd_journal_send_with_location");
+   if (!_eina_sd_journal_send_with_location)
+     {
+        _eina_sd_journal_send_with_location = NULL;
+        eina_module_free(_libsystemd);
+        _libsystemd = NULL;
+        _libsystemd_broken = EINA_TRUE;
+     }
+}
+
+#endif
+
 EAPI void
 eina_log_print_cb_journald(const Eina_Log_Domain *d,
                            Eina_Log_Level level,
@@ -2108,6 +2142,9 @@ eina_log_print_cb_journald(const Eina_Log_Domain *d,
    Eina_Thread cur;
    int r;
 
+   _eina_sd_init();
+   if (!_eina_sd_journal_send_with_location) goto nosystemd;
+
    r = asprintf(&file_prefixed, "CODE_FILE=%s", file);
    if (r == -1)
      {
@@ -2134,12 +2171,12 @@ eina_log_print_cb_journald(const Eina_Log_Domain *d,
 #ifdef EINA_LOG_BACKTRACE
    if (EINA_LIKELY(level > _backtrace_level))
 #endif
-     sd_journal_send_with_location(file_prefixed, line_str, fnc,
-                                   "PRIORITY=%i", level,
-                                   "MESSAGE=%s", message,
-                                   "EFL_DOMAIN=%s", d->domain_str,
-                                   "THREAD=%lu", cur,
-                                   NULL);
+     _eina_sd_journal_send_with_location(file_prefixed, line_str, fnc,
+                                         "PRIORITY=%i", level,
+                                         "MESSAGE=%s", message,
+                                         "EFL_DOMAIN=%s", d->domain_str,
+                                         "THREAD=%lu", cur,
+                                         NULL);
 #ifdef EINA_LOG_BACKTRACE
    else
      {
@@ -2159,14 +2196,14 @@ eina_log_print_cb_journald(const Eina_Log_Domain *d,
           else
             eina_strbuf_append_printf(bts, "[%s], ", strings[i]);
 
-        sd_journal_send_with_location(file_prefixed, line_str, fnc,
-                                      "PRIORITY=%i", level,
-                                      "MESSAGE=%s", message,
-                                      "EFL_DOMAIN=%s", d->domain_str,
-                                      "THREAD=%lu", cur,
-                                      "BACKTRACE=%s",
-                                      eina_strbuf_string_get(bts),
-                                      NULL);
+        _eina_sd_journal_send_with_location(file_prefixed, line_str, fnc,
+                                            "PRIORITY=%i", level,
+                                            "MESSAGE=%s", message,
+                                            "EFL_DOMAIN=%s", d->domain_str,
+                                            "THREAD=%lu", cur,
+                                            "BACKTRACE=%s",
+                                            eina_strbuf_string_get(bts),
+                                            NULL);
         eina_strbuf_free(bts);
         free(strings);
      }
@@ -2176,10 +2213,10 @@ finish:
    free(file_prefixed);
    free(line_str);
    free(message);
-
-#else
-   eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, data, args);
+   return;
+nosystemd:
 #endif
+   eina_log_print_cb_stderr(d, level, file, fnc, line, fmt, data, args);
 }
 
 EAPI void
diff --git a/src/lib/eina/meson.build b/src/lib/eina/meson.build
index 1104ae74c7..ce7cfe84f1 100644
--- a/src/lib/eina/meson.build
+++ b/src/lib/eina/meson.build
@@ -265,14 +265,7 @@ if default_mempool
 endif
 
 if get_option('systemd') == true
-  systemd = dependency('libsystemd')
-  eina_deps += systemd
   config_h.set('HAVE_SYSTEMD', '1')
-  if systemd.version().version_compare('>=209')
-    config_h.set('HAVE_SYSTEMD_LOGIN_209', '1')
-  endif
-else
-  systemd = []
 endif
 
 
diff --git a/src/lib/elput/elput_logind.c b/src/lib/elput/elput_logind.c
index cca5ea7eb7..3548cf4a71 100644
--- a/src/lib/elput/elput_logind.c
+++ b/src/lib/elput/elput_logind.c
@@ -1,6 +1,68 @@
 #include "elput_private.h"
 
-#if defined(HAVE_SYSTEMD) || defined(HAVE_ELOGIND)
+#ifdef HAVE_SYSTEMD
+static Eina_Module *_libsystemd = NULL;
+static Eina_Bool _libsystemd_broken = EINA_FALSE;
+
+static int (*_elput_sd_session_get_vt) (const char *session, unsigned *vtnr) = 
NULL;
+static int (*_elput_sd_session_get_tty) (const char *session, char **display) 
= NULL;
+static int (*_elput_sd_pid_get_session) (pid_t pid, char **session) = NULL;
+static int (*_elput_sd_session_get_seat) (const char *session, char **seat) = 
NULL;
+
+void
+_elput_sd_init(void)
+{
+   if (_libsystemd_broken) return;
+   _libsystemd = eina_module_new("libsystemd.so.0");
+   if (_libsystemd)
+     {
+        if (!eina_module_load(_libsystemd))
+          {
+             eina_module_free(_libsystemd);
+             _libsystemd = NULL;
+          }
+     }
+   if (!_libsystemd)
+     {
+        _libsystemd = eina_module_new("libelogind.so.0");
+        if (_libsystemd)
+          {
+             if (!eina_module_load(_libsystemd))
+               {
+                  eina_module_free(_libsystemd);
+                  _libsystemd = NULL;
+               }
+          }
+     }
+   if (!_libsystemd)
+     {
+        _libsystemd_broken = EINA_TRUE;
+        return;
+     }
+   // sd_session_get_vt == newere in systemd 207
+   _elput_sd_session_get_vt =
+     eina_module_symbol_get(_libsystemd, "sd_session_get_vt");
+   // sd_session_get_tty == older api in ssystemd 198
+   _elput_sd_session_get_tty =
+     eina_module_symbol_get(_libsystemd, "sd_session_get_tty");
+   _elput_sd_pid_get_session =
+     eina_module_symbol_get(_libsystemd, "sd_pid_get_session");
+   _elput_sd_session_get_seat =
+     eina_module_symbol_get(_libsystemd, "sd_session_get_seat");
+   if (((!_elput_sd_session_get_vt) && (!_elput_sd_session_get_tty)) ||
+       (!_elput_sd_pid_get_session) ||
+       (!_elput_sd_session_get_seat))
+     {
+        _elput_sd_session_get_vt = NULL;
+        _elput_sd_session_get_tty = NULL;
+        _elput_sd_pid_get_session = NULL;
+        _elput_sd_session_get_seat = NULL;
+        eina_module_free(_libsystemd);
+        _libsystemd = NULL;
+        _libsystemd_broken = EINA_TRUE;
+     }
+}
+
 
 static void
 _logind_session_active_cb_free(void *data EINA_UNUSED, void *event)
@@ -140,13 +202,16 @@ _cb_device_resumed(void *data, const Eldbus_Message *msg)
 static Eina_Bool
 _logind_session_vt_get(const char *sid, unsigned int *vt)
 {
-# ifdef HAVE_SYSTEMD_LOGIN_209
-   return (sd_session_get_vt(sid, vt) >= 0);
-# else
    int ret = 0;
    char *tty;
 
-   ret = sd_session_get_tty(sid, &tty);
+   _elput_sd_init();
+   if ((!_elput_sd_session_get_vt) && (!_elput_sd_session_get_tty))
+     return EINA_FALSE;
+   if (_elput_sd_session_get_vt)
+     return (_elput_sd_session_get_vt(sid, vt) >= 0);
+
+   ret = _elput_sd_session_get_tty(sid, &tty);
    if (ret < 0) return ret;
 
    ret = sscanf(tty, "tty%u", vt);
@@ -154,7 +219,6 @@ _logind_session_vt_get(const char *sid, unsigned int *vt)
 
    if (ret != 1) return EINA_FALSE;
    return EINA_TRUE;
-# endif
 }
 
 static Eina_Bool
@@ -489,13 +553,16 @@ _logind_connect(Elput_Manager **manager, const char 
*seat, unsigned int tty)
    int ret = 0;
    char *s = NULL;
 
+   _elput_sd_init();
+   if (!_elput_sd_pid_get_session) return EINA_FALSE;
+
    em = calloc(1, sizeof(Elput_Manager));
    if (!em) return EINA_FALSE;
 
    em->interface = &_logind_interface;
    em->seat = eina_stringshare_add(seat);
 
-   ret = sd_pid_get_session(getpid(), &em->sid);
+   ret = _elput_sd_pid_get_session(getpid(), &em->sid);
 
    if (ret < 0)
      {
@@ -508,7 +575,7 @@ _logind_connect(Elput_Manager **manager, const char *seat, 
unsigned int tty)
 
    if (!em->sid) goto session_err;
 
-   ret = sd_session_get_seat(em->sid, &s);
+   ret = _elput_sd_session_get_seat(em->sid, &s);
    if (ret < 0)
      {
         ERR("Failed to get session seat");
diff --git a/src/lib/elput/elput_manager.c b/src/lib/elput/elput_manager.c
index 987e73759b..93f39ea261 100644
--- a/src/lib/elput/elput_manager.c
+++ b/src/lib/elput/elput_manager.c
@@ -2,7 +2,7 @@
 
 static Elput_Interface *_ifaces[] =
 {
-#if defined(HAVE_SYSTEMD) || defined(HAVE_ELOGIND)
+#ifdef HAVE_SYSTEMD
    &_logind_interface,
 #endif
    NULL,
diff --git a/src/lib/elput/elput_private.h b/src/lib/elput/elput_private.h
index 744c5a92e3..fd7d843d2e 100644
--- a/src/lib/elput/elput_private.h
+++ b/src/lib/elput/elput_private.h
@@ -23,14 +23,6 @@
 # include <xkbcommon/xkbcommon.h>
 # include <xkbcommon/xkbcommon-compose.h>
 
-# ifdef HAVE_SYSTEMD
-#  include <systemd/sd-login.h>
-# endif
-
-# ifdef HAVE_ELOGIND
-#  include <elogind/sd-login.h>
-# endif
-
 #ifndef ELPUT_NODEFS
 # ifdef ELPUT_DEFAULT_LOG_COLOR
 #  undef ELPUT_DEFAULT_LOG_COLOR
diff --git a/src/lib/elput/meson.build b/src/lib/elput/meson.build
index 2aa3590d2b..0e3e2f9c5f 100644
--- a/src/lib/elput/meson.build
+++ b/src/lib/elput/meson.build
@@ -19,12 +19,6 @@ elput_src = [
 elput_deps += dependency('libinput', version : ['>=1.7.0'])
 elput_deps += dependency('xkbcommon', version : ['>=0.3.0'])
 elput_deps += dependency('libudev')
-if get_option('systemd')
-  elput_deps += systemd
-endif
-if get_option('elogind')
-  elput_deps += dependency('libelogind')
-endif
 
 elput_lib = library('elput',
     elput_src, pub_eo_file_target,

-- 


Reply via email to