]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Fix output value of sd_seat_get_sessions() and drop FOREACH_WORD use
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 30 Jul 2020 10:43:07 +0000 (12:43 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 9 Sep 2020 07:34:54 +0000 (09:34 +0200)
sd_seat_get_sessions() would return 0 in the 'n_uids' (now 'ret_n_uids') output
parameter when 'uid' (now 'ret_uids') was passed as NULL.

While at it, drop FOREACH_WORD() use.

Also use any whitespace as separator. In practice this shouldn't matter, since
logind always uses spaces, but it seems nicer to not specify this explicitly,
and the default is more flexible.

man/sd_seat_get_active.xml
src/libsystemd/sd-login/sd-login.c
src/systemd/sd-login.h

index cf70b35785a58255fb56ad9f40c3e7042e355fa9..94401caa7280335d5e9fcaee8cbae92f4ba590d7 100644 (file)
@@ -38,9 +38,9 @@
       <funcprototype>
         <funcdef>int <function>sd_seat_get_sessions</function></funcdef>
         <paramdef>const char *<parameter>seat</parameter></paramdef>
-        <paramdef>char ***<parameter>sessions</parameter></paramdef>
-        <paramdef>uid_t **<parameter>uid</parameter></paramdef>
-        <paramdef>unsigned int *<parameter>n_uids</parameter></paramdef>
+        <paramdef>char ***<parameter>ret_sessions</parameter></paramdef>
+        <paramdef>uid_t **<parameter>ret_uids</parameter></paramdef>
+        <paramdef>unsigned int *<parameter>ret_n_uids</parameter></paramdef>
       </funcprototype>
 
       <funcprototype>
     <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
     call after use.</para>
 
-    <para><function>sd_seat_get_sessions()</function> may be used to
-    determine all sessions on the specified seat. Returns two arrays,
-    one (<constant>NULL</constant> terminated) with the session
-    identifiers of the sessions and one with the user identifiers of
-    the Unix users the sessions belong to. An additional parameter may
-    be used to return the number of entries in the latter array. This
-    value is the same the return value, if the latter is nonnegative.
-    The two arrays and the last parameter may be passed as
-    <constant>NULL</constant> in case these values need not to be
-    determined. The arrays and the strings referenced by them need to
-    be freed with the libc
-    <citerefentry project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
-    call after use. Note that instead of an empty array
-    <constant>NULL</constant> may be returned and should be considered
-    equivalent to an empty array.</para>
+    <para><function>sd_seat_get_sessions()</function> may be used to determine all sessions on the specified
+    seat. Returns two arrays, one (<constant>NULL</constant> terminated) with the session identifiers of the
+    sessions and one with the user identifiers of the Unix users the sessions belong to. An additional
+    parameter may be used to return the number of entries in the latter array. This value is the same as the
+    return value if the return value is nonnegative. The output parameters may be passed as
+    <constant>NULL</constant> in case these output values are not needed. The arrays and the strings
+    referenced by them need to be freed with the libc <citerefentry
+    project='man-pages'><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry> call after
+    use. Note that instead of an empty array <constant>NULL</constant> may be returned and should be
+    considered equivalent to an empty array.</para>
 
     <para><function>sd_seat_can_tty()</function> may be used to
     determine whether a specific seat provides TTY functionality, i.e.
index 6412002f490ded46af3f85b183f476926368df28..14e046872064abb84edb6494fdd890d103120399 100644 (file)
@@ -378,7 +378,7 @@ static int uid_get_array(uid_t uid, const char *variable, char ***array) {
         if (r < 0)
                 return r;
 
-        a = strv_split(s, " ");
+        a = strv_split(s, NULL);
         if (!a)
                 return -ENOMEM;
 
@@ -650,73 +650,70 @@ _public_ int sd_seat_get_active(const char *seat, char **session, uid_t *uid) {
         return 0;
 }
 
-_public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uids, unsigned *n_uids) {
-        _cleanup_free_ char *p = NULL, *s = NULL, *t = NULL;
-        _cleanup_strv_free_ char **a = NULL;
-        _cleanup_free_ uid_t *b = NULL;
-        unsigned n = 0;
+_public_ int sd_seat_get_sessions(
+                const char *seat,
+                char ***ret_sessions,
+                uid_t **ret_uids,
+                unsigned *ret_n_uids) {
+
+        _cleanup_free_ char *fname = NULL, *session_line = NULL, *uid_line = NULL;
+        _cleanup_strv_free_ char **sessions = NULL;
+        _cleanup_free_ uid_t *uids = NULL;
+        unsigned n_sessions = 0;
         int r;
 
-        r = file_of_seat(seat, &p);
+        r = file_of_seat(seat, &fname);
         if (r < 0)
                 return r;
 
-        r = parse_env_file(NULL, p,
-                           "SESSIONS", &s,
-                           "UIDS", &t);
+        r = parse_env_file(NULL, fname,
+                           "SESSIONS", &session_line,
+                           "UIDS", &uid_line);
         if (r == -ENOENT)
                 return -ENXIO;
         if (r < 0)
                 return r;
 
-        if (s) {
-                a = strv_split(s, " ");
-                if (!a)
+        if (session_line) {
+                sessions = strv_split(session_line, NULL);
+                if (!sessions)
                         return -ENOMEM;
-        }
-
-        if (uids && t) {
-                const char *word, *state;
-                size_t l;
-
-                FOREACH_WORD(word, l, t, state)
-                        n++;
-
-                if (n > 0) {
-                        unsigned i = 0;
 
-                        b = new(uid_t, n);
-                        if (!b)
-                                return -ENOMEM;
+                n_sessions = strv_length(sessions);
+        };
 
-                        FOREACH_WORD(word, l, t, state) {
-                                _cleanup_free_ char *k = NULL;
+        if (ret_uids && uid_line) {
+                uids = new(uid_t, n_sessions);
+                if (!uids)
+                        return -ENOMEM;
 
-                                k = strndup(word, l);
-                                if (!k)
-                                        return -ENOMEM;
+                size_t n = 0;
+                for (const char *p = uid_line;;) {
+                        _cleanup_free_ char *word = NULL;
 
-                                r = parse_uid(k, b + i);
-                                if (r < 0)
-                                        return r;
+                        r = extract_first_word(&p, &word, NULL, 0);
+                        if (r < 0)
+                                return r;
+                        if (r == 0)
+                                break;
 
-                                i++;
-                        }
+                        r = parse_uid(word, &uids[n++]);
+                        if (r < 0)
+                                return r;
                 }
-        }
 
-        r = (int) strv_length(a);
-
-        if (sessions)
-                *sessions = TAKE_PTR(a);
-
-        if (uids)
-                *uids = TAKE_PTR(b);
+                if (n != n_sessions)
+                        return -EUCLEAN;
+        }
 
-        if (n_uids)
-                *n_uids = n;
+        if (ret_sessions)
+                *ret_sessions = TAKE_PTR(sessions);
+        if (ret_uids)
+                *ret_uids = TAKE_PTR(uids);
+        if (ret_n_uids)
+                *ret_n_uids = n_sessions;
 
-        return r;
+        return n_sessions;
 }
 
 static int seat_get_can(const char *seat, const char *variable) {
index e18f01bb671de665892c01c4e333a80a34dccf01..360f44d341e8418f0f6ae85d1eea935489726ac6 100644 (file)
@@ -180,7 +180,11 @@ int sd_seat_get_active(const char *seat, char **session, uid_t *uid);
 
 /* Return sessions and users on seat. Returns number of sessions.
  * If sessions is NULL, this returns only the number of sessions. */
-int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uid, unsigned *n_uids);
+int sd_seat_get_sessions(
+                const char *seat,
+                char ***ret_sessions,
+                uid_t **ret_uids,
+                unsigned *ret_n_uids);
 
 /* Return whether the seat is multi-session capable */
 int sd_seat_can_multi_session(const char *seat) _sd_deprecated_;