[systemd-commits] 8 commits - man/pam_systemd.xml man/sd_session_is_active.xml src/libsystemd src/libsystemd-terminal src/shared src/systemd src/test

David Herrmann dvdhrm at kemper.freedesktop.org
Mon Sep 22 05:29:06 PDT 2014


 man/pam_systemd.xml                  |    4 ++
 man/sd_session_is_active.xml         |   23 ++++++++++++++++
 src/libsystemd-terminal/evcat.c      |    3 ++
 src/libsystemd-terminal/idev-evdev.c |   49 +++++++++++++++++++++++++----------
 src/libsystemd-terminal/modeset.c    |   14 +++++-----
 src/libsystemd-terminal/sysview.c    |   34 +++++++++++++++++++++---
 src/libsystemd-terminal/sysview.h    |   14 +++++-----
 src/libsystemd/libsystemd.sym.m4     |    7 ++++-
 src/libsystemd/sd-bus/bus-control.c  |   14 +++++-----
 src/libsystemd/sd-bus/bus-kernel.c   |   26 ++++++++++--------
 src/libsystemd/sd-bus/bus-message.c  |    2 -
 src/libsystemd/sd-login/sd-login.c   |   19 +++++++++++++
 src/shared/util.h                    |   16 +++++++++++
 src/systemd/sd-login.h               |    3 ++
 src/test/test-util.c                 |   42 ++++++++++++++++++++++++++----
 15 files changed, 211 insertions(+), 59 deletions(-)

New commits:
commit c72d5456e2d6a6c8cefbfc16a542ae03a769397f
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Sat Sep 20 18:42:29 2014 +0200

    login: add public sd_session_get_desktop() API
    
    The desktop brand is stored as DESKTOP variable for sessions. It can be
    set arbitrarily by the session owner and identifies the desktop
    environment that is running on that session.

diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml
index 52dfe9d..4df26a3 100644
--- a/man/pam_systemd.xml
+++ b/man/pam_systemd.xml
@@ -268,7 +268,9 @@
                                 as defined by the <ulink
                                 url="http://standards.freedesktop.org/desktop-entry-spec/latest/">Desktop
                                 Entry
-                                Specification</ulink>.</para></listitem>
+                                Specification</ulink>. See
+                                <citerefentry><refentrytitle>sd_session_get_desktop</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                                for more details.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
index 5006be4..e984066 100644
--- a/man/sd_session_is_active.xml
+++ b/man/sd_session_is_active.xml
@@ -51,6 +51,7 @@
                 <refname>sd_session_get_service</refname>
                 <refname>sd_session_get_type</refname>
                 <refname>sd_session_get_class</refname>
+                <refname>sd_session_get_desktop</refname>
                 <refname>sd_session_get_display</refname>
                 <refname>sd_session_get_tty</refname>
                 <refname>sd_session_get_vt</refname>
@@ -110,6 +111,12 @@
                         </funcprototype>
 
                         <funcprototype>
+                                <funcdef>int <function>sd_session_get_desktop</function></funcdef>
+                                <paramdef>const char *<parameter>session</parameter></paramdef>
+                                <paramdef>char **<parameter>desktop</parameter></paramdef>
+                        </funcprototype>
+
+                        <funcprototype>
                                 <funcdef>int <function>sd_session_get_display</function></funcdef>
                                 <paramdef>const char *<parameter>session</parameter></paramdef>
                                 <paramdef>char **<parameter>display</parameter></paramdef>
@@ -218,6 +225,22 @@
                 <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
                 call after use.</para>
 
+                <para><function>sd_session_get_desktop()</function> may
+                be used to determine the brand of the desktop running on
+                the session identified by the specified session identifier.
+                This field can be set freely by desktop environments and
+                does not follow any special formatting. However, desktops
+                are strongly recommended to use the same identifiers and
+                capitalization as for
+                <varname>$XDG_CURRENT_DESKTOP</varname>, as defined by
+                the <ulink
+                url="http://standards.freedesktop.org/desktop-entry-spec/latest/">Desktop
+                Entry
+                Specification</ulink>. The returned string needs to be
+                freed with the libc
+                <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+                call after use.</para>
+
                 <para><function>sd_session_get_display()</function>
                 may be used to determine the X11 display of the
                 session identified by the specified session
diff --git a/src/libsystemd/libsystemd.sym.m4 b/src/libsystemd/libsystemd.sym.m4
index d1450fb..87da7ac 100644
--- a/src/libsystemd/libsystemd.sym.m4
+++ b/src/libsystemd/libsystemd.sym.m4
@@ -153,6 +153,11 @@ global:
         sd_machine_get_ifindices;
 } LIBSYSTEMD_214;
 
+LIBSYSTEMD_217 {
+global:
+        sd_session_get_desktop;
+} LIBSYSTEMD_216;
+
 m4_ifdef(`ENABLE_KDBUS',
 LIBSYSTEMD_FUTURE {
 global:
@@ -438,5 +443,5 @@ global:
         /* sd-path */
         sd_path_home;
         sd_path_search;
-} LIBSYSTEMD_216;
+} LIBSYSTEMD_217;
 )
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index 95cb6ff..c72d23e 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -485,6 +485,25 @@ _public_ int sd_session_get_class(const char *session, char **class) {
         return session_get_string(session, "CLASS", class);
 }
 
+_public_ int sd_session_get_desktop(const char *session, char **desktop) {
+        _cleanup_free_ char *escaped = NULL;
+        char *t;
+        int r;
+
+        assert_return(desktop, -EINVAL);
+
+        r = session_get_string(session, "DESKTOP", &escaped);
+        if (r < 0)
+                return r;
+
+        t = cunescape(escaped);
+        if (!t)
+                return -ENOMEM;
+
+        *desktop = t;
+        return 0;
+}
+
 _public_ int sd_session_get_display(const char *session, char **display) {
         return session_get_string(session, "DISPLAY", display);
 }
diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h
index 1eb3be3..93af197 100644
--- a/src/systemd/sd-login.h
+++ b/src/systemd/sd-login.h
@@ -147,6 +147,9 @@ int sd_session_get_type(const char *session, char **type);
 /* Determine the class of this session, i.e. one of "user", "greeter" or "lock-screen". */
 int sd_session_get_class(const char *session, char **clazz);
 
+/* Determine the desktop brand of this session, i.e. something like "GNOME", "KDE" or "SYSTEMD-CONSOLE". */
+int sd_session_get_desktop(const char *session, char **desktop);
+
 /* Determine the X11 display of this session. */
 int sd_session_get_display(const char *session, char **display);
 

commit 7f3d3ba1a61f28a951ca5fbe59ed15c7ce55219c
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Mon Sep 22 12:49:47 2014 +0200

    bus: align kdbus ioctl parameters to 8byte
    
    All kdbus ioctl arguments must be 8byte aligned. Make sure we use
    alloca_align() and _alignas_(8) in all situations where gcc doesn't
    guarantee 8-byte alignment.
    
    Note that objects on the stack are always 8byte aligned as we put
    _alignas_(8) into the structure definition in kdbus.h.

diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c
index ad372f6..5ac48c0 100644
--- a/src/libsystemd/sd-bus/bus-control.c
+++ b/src/libsystemd/sd-bus/bus-control.c
@@ -60,7 +60,7 @@ static int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags
 
         l = strlen(name);
         size = offsetof(struct kdbus_cmd_name, name) + l + 1;
-        n = alloca0(size);
+        n = alloca0_align(size, 8);
         n->size = size;
         kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags);
         memcpy(n->name, name, l+1);
@@ -151,7 +151,7 @@ static int bus_release_name_kernel(sd_bus *bus, const char *name) {
         assert(name);
 
         l = strlen(name);
-        n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1);
+        n = alloca0_align(offsetof(struct kdbus_cmd_name, name) + l + 1, 8);
         n->size = offsetof(struct kdbus_cmd_name, name) + l + 1;
         memcpy(n->name, name, l+1);
 
@@ -376,11 +376,11 @@ static int bus_get_owner_kdbus(
                 return r;
         if (r > 0) {
                 size = offsetof(struct kdbus_cmd_conn_info, name);
-                cmd = alloca0(size);
+                cmd = alloca0_align(size, 8);
                 cmd->id = id;
         } else {
                 size = offsetof(struct kdbus_cmd_conn_info, name) + strlen(name) + 1;
-                cmd = alloca0(size);
+                cmd = alloca0_align(size, 8);
                 strcpy(cmd->name, name);
         }
 
@@ -827,7 +827,7 @@ static int add_name_change_match(sd_bus *bus,
                             offsetof(struct kdbus_notify_name_change, name) +
                             l);
 
-                m = alloca0(sz);
+                m = alloca0_align(sz, 8);
                 m->size = sz;
                 m->cookie = cookie;
 
@@ -887,7 +887,7 @@ static int add_name_change_match(sd_bus *bus,
                             offsetof(struct kdbus_item, id_change) +
                             sizeof(struct kdbus_notify_id_change));
 
-                m = alloca0(sz);
+                m = alloca0_align(sz, 8);
                 m->size = sz;
                 m->cookie = cookie;
 
@@ -1057,7 +1057,7 @@ int bus_add_match_internal_kernel(
         if (using_bloom)
                 sz += ALIGN8(offsetof(struct kdbus_item, data64) + bus->bloom_size);
 
-        m = alloca0(sz);
+        m = alloca0_align(sz, 8);
         m->size = sz;
         m->cookie = cookie;
 
diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c
index b3cc996..c30491e 100644
--- a/src/libsystemd/sd-bus/bus-kernel.c
+++ b/src/libsystemd/sd-bus/bus-kernel.c
@@ -709,7 +709,7 @@ int bus_kernel_take_fd(sd_bus *b) {
                 sz += ALIGN8(offsetof(struct kdbus_item, str) + l + 1);
         }
 
-        hello = alloca0(sz);
+        hello = alloca0_align(sz, 8);
         hello->size = sz;
         hello->conn_flags = b->hello_flags;
         hello->attach_flags = b->attach_flags;
@@ -796,7 +796,7 @@ int bus_kernel_connect(sd_bus *b) {
 }
 
 static void close_kdbus_msg(sd_bus *bus, struct kdbus_msg *k) {
-        uint64_t off;
+        uint64_t off _alignas_(8);
         struct kdbus_item *d;
 
         assert(bus);
@@ -1268,10 +1268,11 @@ int bus_kernel_create_bus(const char *name, bool world, char **s) {
         if (fd < 0)
                 return -errno;
 
-        make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
-                              offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
-                              offsetof(struct kdbus_item, str) +
-                              DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1));
+        make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
+                                    offsetof(struct kdbus_item, data64) + sizeof(uint64_t) +
+                                    offsetof(struct kdbus_item, str) +
+                                    DECIMAL_STR_MAX(uid_t) + 1 + strlen(name) + 1),
+                             8);
 
         make->size = offsetof(struct kdbus_cmd_make, items);
 
@@ -1423,7 +1424,7 @@ int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char *
         size = ALIGN8(offsetof(struct kdbus_cmd_make, items));
         size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(ep_name) + 1);
 
-        make = alloca0(size);
+        make = alloca0_align(size, 8);
         make->size = size;
         make->flags = KDBUS_MAKE_ACCESS_WORLD;
 
@@ -1472,7 +1473,7 @@ int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) {
                 size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
         }
 
-        update = alloca0(size);
+        update = alloca0_align(size, 8);
         update->size = size;
 
         n = update->items;
@@ -1528,7 +1529,7 @@ int bus_kernel_make_starter(
                ALIGN8(offsetof(struct kdbus_item, str) + strlen(name) + 1) +
                policy_cnt * ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access));
 
-        hello = alloca0(size);
+        hello = alloca0_align(size, 8);
 
         n = hello->items;
         strcpy(n->str, name);
@@ -1588,9 +1589,10 @@ int bus_kernel_create_domain(const char *name, char **s) {
         if (fd < 0)
                 return -errno;
 
-        make = alloca0(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
-                              offsetof(struct kdbus_item, str) +
-                              strlen(name) + 1));
+        make = alloca0_align(ALIGN8(offsetof(struct kdbus_cmd_make, items) +
+                                    offsetof(struct kdbus_item, str) +
+                                    strlen(name) + 1),
+                             8);
 
         n = make->items;
         strcpy(n->str, name);
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
index 1fa3ad2..400ba30 100644
--- a/src/libsystemd/sd-bus/bus-message.c
+++ b/src/libsystemd/sd-bus/bus-message.c
@@ -128,7 +128,7 @@ static void message_free(sd_bus_message *m) {
         message_reset_parts(m);
 
         if (m->release_kdbus) {
-                uint64_t off;
+                uint64_t off _alignas_(8);
 
                 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
                 ioctl(m->bus->input_fd, KDBUS_CMD_FREE, &off);

commit 95d78c7e7c81a6b788f28c33ef2cafd87471a0d7
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Mon Sep 22 12:05:16 2014 +0200

    util: add alloca_align()
    
    The alloca_align() helper is the alloca() equivalent of posix_memalign().
    As there is no such function provided by glibc, we simply account for
    additional memory and return a pointer offset into the allocated memory to
    grant the alignment.
    
    Furthermore, alloca0_align() is added, which simply clears the allocated
    memory.

diff --git a/src/shared/util.h b/src/shared/util.h
index 08d556f..a1d5657 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -852,6 +852,22 @@ int unlink_noerrno(const char *path);
                 (void *) memset(_new_, 0, _len_);       \
         })
 
+#define alloca_align(size, align)                                       \
+        ({                                                              \
+                void *_ptr_;                                            \
+                size_t _mask_ = (align) - 1;                            \
+                _ptr_ = alloca((size) + _mask_);                        \
+                (void*)(((uintptr_t)_ptr_ + _mask_) & ~_mask_);         \
+        })
+
+#define alloca0_align(size, align)                                      \
+        ({                                                              \
+                void *_new_;                                            \
+                size_t _size_ = (size);                                 \
+                _new_ = alloca_align(_size_, (align));                  \
+                (void*)memset(_new_, 0, _size_);                        \
+        })
+
 #define strappenda(a, ...)                                       \
         ({                                                       \
                 int _len = strlen(a);                            \
diff --git a/src/test/test-util.c b/src/test/test-util.c
index f8e42f3..1311184 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -131,6 +131,19 @@ static void test_container_of(void) {
                                v1) == &myval);
 }
 
+static void test_alloca(void) {
+        static const uint8_t zero[997] = { };
+        char *t;
+
+        t = alloca_align(17, 512);
+        assert_se(!((uintptr_t)t & 0xff));
+        memzero(t, 17);
+
+        t = alloca0_align(997, 1024);
+        assert_se(!((uintptr_t)t & 0x1ff));
+        assert_se(!memcmp(t, zero, 997));
+}
+
 static void test_first_word(void) {
         assert_se(first_word("Hello", ""));
         assert_se(first_word("Hello", "Hello"));
@@ -1272,6 +1285,7 @@ int main(int argc, char *argv[]) {
         test_align_power2();
         test_max();
         test_container_of();
+        test_alloca();
         test_first_word();
         test_close_many();
         test_parse_boolean();

commit eee846339d2f76f568c62b3725bf75bcee728115
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Mon Sep 22 11:27:22 2014 +0200

    test-util: make valgrind happy
    
    Properly free all temporary resources to make valgrind not complain about
    lost records.

diff --git a/src/test/test-util.c b/src/test/test-util.c
index 80425ca..f8e42f3 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -843,11 +843,27 @@ static void test_is_valid_documentation_url(void) {
 }
 
 static void test_file_in_same_dir(void) {
-        assert_se(streq(file_in_same_dir("/", "a"), "/a"));
-        assert_se(streq(file_in_same_dir("/", "/a"), "/a"));
-        assert_se(streq(file_in_same_dir("", "a"), "a"));
-        assert_se(streq(file_in_same_dir("a/", "a"), "a/a"));
-        assert_se(streq(file_in_same_dir("bar/foo", "bar"), "bar/bar"));
+        char *t;
+
+        t = file_in_same_dir("/", "a");
+        assert_se(streq(t, "/a"));
+        free(t);
+
+        t = file_in_same_dir("/", "/a");
+        assert_se(streq(t, "/a"));
+        free(t);
+
+        t = file_in_same_dir("", "a");
+        assert_se(streq(t, "a"));
+        free(t);
+
+        t = file_in_same_dir("a/", "a");
+        assert_se(streq(t, "a/a"));
+        free(t);
+
+        t = file_in_same_dir("bar/foo", "bar");
+        assert_se(streq(t, "bar/bar"));
+        free(t);
 }
 
 static void test_endswith(void) {
@@ -1239,11 +1255,13 @@ static void test_unquote_many_words(void) {
         assert_se(unquote_many_words(&p, &a, NULL) == 1);
         assert_se(p == original+7);
         assert_se(streq_ptr(a, "foobar"));
+        free(a);
 
         p = original = "     foobar    ";
         assert_se(unquote_many_words(&p, &a, NULL) == 1);
         assert_se(p == original+15);
         assert_se(streq_ptr(a, "foobar"));
+        free(a);
 }
 
 int main(int argc, char *argv[]) {

commit f6e3ee1493f20823b2c33465458b92f3581af88d
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Sat Sep 20 17:47:56 2014 +0200

    terminal: raise sysview DEVICE_CHANGE events per attachment
    
    Instead of raising DEVICE_CHANGE only per device, we now raise it per
    device-session attachment. This is what we want for all sysview users,
    anyway, as sessions are meant to be independent of each other. Lets avoid
    any external session iterators and just do that in sysview itself.

diff --git a/src/libsystemd-terminal/modeset.c b/src/libsystemd-terminal/modeset.c
index 33c79a2..7a28e7a 100644
--- a/src/libsystemd-terminal/modeset.c
+++ b/src/libsystemd-terminal/modeset.c
@@ -348,6 +348,13 @@ static int modeset_sysview_fn(sysview_context *c, void *userdata, sysview_event
                         grdev_session_remove_drm(m->grdev_session, sysview_device_get_ud(d));
 
                 break;
+        case SYSVIEW_EVENT_SESSION_REFRESH:
+                d = ev->session_refresh.device;
+                type = sysview_device_get_type(d);
+                if (type == SYSVIEW_DEVICE_DRM)
+                        grdev_session_hotplug_drm(m->grdev_session, ev->session_refresh.ud);
+
+                break;
         case SYSVIEW_EVENT_SESSION_CONTROL:
                 r = ev->session_control.error;
                 if (r < 0) {
@@ -362,13 +369,6 @@ static int modeset_sysview_fn(sysview_context *c, void *userdata, sysview_event
                 }
 
                 break;
-        case SYSVIEW_EVENT_DEVICE_CHANGE:
-                d = ev->device_change.device;
-                type = sysview_device_get_type(d);
-                if (type == SYSVIEW_DEVICE_DRM)
-                        grdev_session_hotplug_drm(m->grdev_session, ev->device_change.ud);
-
-                break;
         }
 
         return 0;
diff --git a/src/libsystemd-terminal/sysview.c b/src/libsystemd-terminal/sysview.c
index 161ea11..5b623c1 100644
--- a/src/libsystemd-terminal/sysview.c
+++ b/src/libsystemd-terminal/sysview.c
@@ -517,10 +517,11 @@ static int context_raise_session_detach(sysview_context *c, sysview_session *ses
         return context_raise(c, &event, 0);
 }
 
-static int context_raise_device_change(sysview_context *c, sysview_device *device, struct udev_device *ud) {
+static int context_raise_session_refresh(sysview_context *c, sysview_session *session, sysview_device *device, struct udev_device *ud) {
         sysview_event event = {
-                .type = SYSVIEW_EVENT_DEVICE_CHANGE,
-                .device_change = {
+                .type = SYSVIEW_EVENT_SESSION_REFRESH,
+                .session_refresh = {
+                        .session = session,
                         .device = device,
                         .ud = ud,
                 }
@@ -581,6 +582,31 @@ static int context_remove_device(sysview_context *c, sysview_device *device) {
         return error;
 }
 
+static int context_change_device(sysview_context *c, sysview_device *device, struct udev_device *ud) {
+        sysview_session *session;
+        int r, error = 0;
+        Iterator i;
+
+        assert(c);
+        assert(device);
+
+        log_debug("sysview: change device '%s'", device->name);
+
+        HASHMAP_FOREACH(session, device->seat->session_map, i) {
+                if (!session->public)
+                        continue;
+
+                r = context_raise_session_refresh(c, session, device, ud);
+                if (r != 0)
+                        error = r;
+        }
+
+        if (error < 0)
+                log_debug("sysview: error while changing device '%s': %s",
+                          device->name, strerror(-r));
+        return error;
+}
+
 static int context_add_session(sysview_context *c, sysview_seat *seat, const char *id) {
         sysview_session *session;
         sysview_device *device;
@@ -884,7 +910,7 @@ static int context_ud_hotplug(sysview_context *c, struct udev_device *d) {
                 if (!device)
                         return 0;
 
-                return context_raise_device_change(c, device, d);
+                return context_change_device(c, device, d);
         } else if (!action || streq_ptr(action, "add")) {
                 struct udev_device *p;
                 unsigned int type, t;
diff --git a/src/libsystemd-terminal/sysview.h b/src/libsystemd-terminal/sysview.h
index b9452fa..4d800f8 100644
--- a/src/libsystemd-terminal/sysview.h
+++ b/src/libsystemd-terminal/sysview.h
@@ -63,9 +63,8 @@ enum {
         SYSVIEW_EVENT_SESSION_REMOVE,
         SYSVIEW_EVENT_SESSION_ATTACH,
         SYSVIEW_EVENT_SESSION_DETACH,
+        SYSVIEW_EVENT_SESSION_REFRESH,
         SYSVIEW_EVENT_SESSION_CONTROL,
-
-        SYSVIEW_EVENT_DEVICE_CHANGE,
 };
 
 struct sysview_event {
@@ -94,13 +93,14 @@ struct sysview_event {
 
                 struct {
                         sysview_session *session;
-                        int error;
-                } session_control;
-
-                struct {
                         sysview_device *device;
                         struct udev_device *ud;
-                } device_change;
+                } session_refresh;
+
+                struct {
+                        sysview_session *session;
+                        int error;
+                } session_control;
         };
 };
 

commit 89febb631a4710992cd41e402a643451b19c11a7
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Sat Sep 20 12:39:59 2014 +0200

    terminal: forward evdev RESYNC events to linked devices
    
    Whenever we resync an evdev device (or disable it), we should send RESYNC
    events to the linked upper layers. This allows to disable key-repeat and
    assume some events got dropped.

diff --git a/src/libsystemd-terminal/idev-evdev.c b/src/libsystemd-terminal/idev-evdev.c
index 25ac849..719e18c 100644
--- a/src/libsystemd-terminal/idev-evdev.c
+++ b/src/libsystemd-terminal/idev-evdev.c
@@ -102,7 +102,16 @@ static void idev_evdev_name(char *out, dev_t devnum) {
         sprintf(out, "evdev/%u:%u", major(devnum), minor(devnum));
 }
 
-static int idev_evdev_raise(idev_evdev *evdev, struct input_event *event) {
+static int idev_evdev_feed_resync(idev_evdev *evdev) {
+        idev_data data = {
+                .type = IDEV_DATA_RESYNC,
+                .resync = evdev->resync,
+        };
+
+        return idev_element_feed(&evdev->element, &data);
+}
+
+static int idev_evdev_feed_evdev(idev_evdev *evdev, struct input_event *event) {
         idev_data data = {
                 .type = IDEV_DATA_EVDEV,
                 .resync = evdev->resync,
@@ -156,7 +165,6 @@ static int idev_evdev_io(idev_evdev *evdev) {
          * case we cannot keep up with the kernel.
          * TODO: Make sure libevdev always reports SYN_DROPPED to us, regardless
          * whether any event was synced afterwards.
-         * TODO: Forward SYN_DROPPED to attached devices.
          */
 
         flags = LIBEVDEV_READ_FLAG_NORMAL;
@@ -191,7 +199,7 @@ static int idev_evdev_io(idev_evdev *evdev) {
                 } else if (r == LIBEVDEV_READ_STATUS_SYNC) {
                         if (evdev->resync) {
                                 /* sync-event */
-                                r = idev_evdev_raise(evdev, &ev);
+                                r = idev_evdev_feed_evdev(evdev, &ev);
                                 if (r != 0) {
                                         error = r;
                                         break;
@@ -200,10 +208,15 @@ static int idev_evdev_io(idev_evdev *evdev) {
                                 /* start of sync */
                                 evdev->resync = true;
                                 flags = LIBEVDEV_READ_FLAG_SYNC;
+                                r = idev_evdev_feed_resync(evdev);
+                                if (r != 0) {
+                                        error = r;
+                                        break;
+                                }
                         }
                 } else {
                         /* normal event */
-                        r = idev_evdev_raise(evdev, &ev);
+                        r = idev_evdev_feed_evdev(evdev, &ev);
                         if (r != 0) {
                                 error = r;
                                 break;
@@ -288,6 +301,7 @@ static void idev_evdev_disable(idev_evdev *evdev) {
                 return;
 
         evdev->running = false;
+        idev_evdev_feed_resync(evdev);
         sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_OFF);
         sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_OFF);
 }

commit 6022343476982439dfc2e06bf54db78a0c8c6bff
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Sat Sep 20 12:34:43 2014 +0200

    terminal: always call _enable/_disable on evdev devices
    
    The current pause/resume logic kinda intertwines the resume/pause and
    enable/disable functions. Lets avoid that non-obvious behavior and always
    make resume call into enable, and pause call into disable, if appropriate.

diff --git a/src/libsystemd-terminal/idev-evdev.c b/src/libsystemd-terminal/idev-evdev.c
index 18c48ee..25ac849 100644
--- a/src/libsystemd-terminal/idev-evdev.c
+++ b/src/libsystemd-terminal/idev-evdev.c
@@ -49,6 +49,7 @@ struct idev_evdev {
 
         bool unsync : 1;                /* not in-sync with kernel */
         bool resync : 1;                /* re-syncing with kernel */
+        bool running : 1;
 };
 
 struct unmanaged_evdev {
@@ -268,6 +269,12 @@ static void idev_evdev_enable(idev_evdev *evdev) {
         assert(evdev->fd_src);
         assert(evdev->idle_src);
 
+        if (evdev->running)
+                return;
+        if (evdev->fd < 0 || evdev->element.n_open < 1 || !evdev->element.enabled)
+                return;
+
+        evdev->running = true;
         sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_ON);
         sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_ONESHOT);
 }
@@ -277,6 +284,10 @@ static void idev_evdev_disable(idev_evdev *evdev) {
         assert(evdev->fd_src);
         assert(evdev->idle_src);
 
+        if (!evdev->running)
+                return;
+
+        evdev->running = false;
         sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_OFF);
         sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_OFF);
 }
@@ -288,9 +299,7 @@ static int idev_evdev_resume(idev_evdev *evdev, int dev_fd) {
 
         if (fd < 0 || evdev->fd == fd) {
                 fd = -1;
-                if (evdev->fd >= 0 && e->n_open > 0 && e->enabled)
-                        idev_evdev_enable(evdev);
-
+                idev_evdev_enable(evdev);
                 return 0;
         }
 
@@ -351,15 +360,14 @@ static int idev_evdev_resume(idev_evdev *evdev, int dev_fd) {
                 return r;
         }
 
-        if (e->n_open < 1 || !e->enabled) {
-                sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_OFF);
-                sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_OFF);
-        }
+        sd_event_source_set_enabled(evdev->fd_src, SD_EVENT_OFF);
+        sd_event_source_set_enabled(evdev->idle_src, SD_EVENT_OFF);
 
         evdev->unsync = true;
         evdev->fd = fd;
-
         fd = -1;
+
+        idev_evdev_enable(evdev);
         return 0;
 }
 
@@ -371,12 +379,11 @@ static void idev_evdev_pause(idev_evdev *evdev, bool release) {
 
         log_debug("idev-evdev: %s/%s: pause", e->session->name, e->name);
 
+        idev_evdev_disable(evdev);
         if (release) {
                 evdev->idle_src = sd_event_source_unref(evdev->idle_src);
                 evdev->fd_src = sd_event_source_unref(evdev->fd_src);
                 evdev->fd = safe_close(evdev->fd);
-        } else {
-                idev_evdev_disable(evdev);
         }
 }
 

commit 4c4e4128f3763eb3d4836a23b9c46b6122e81d62
Author: David Herrmann <dh.herrmann at gmail.com>
Date:   Sat Sep 20 12:33:18 2014 +0200

    terminal: print RESYNC state in evcat
    
    Whenever a key-event is part of a RESYNC, we should print that verbosely
    as those events are out-of-order.

diff --git a/src/libsystemd-terminal/evcat.c b/src/libsystemd-terminal/evcat.c
index 8c27fb2..b3f08e6 100644
--- a/src/libsystemd-terminal/evcat.c
+++ b/src/libsystemd-terminal/evcat.c
@@ -203,6 +203,9 @@ static void kdata_print(idev_data *data) {
                         k->value == 1 ? "DOWN" :
                         "REPEAT");
 
+        /* Resync state */
+        printf(" | %-6s", data->resync ? "RESYNC" : "");
+
         /* Keycode that triggered the event */
         printf(" | %5u", (unsigned)k->keycode);
 



More information about the systemd-commits mailing list