GetCurrentUser reads from a file where possible 55/325355/5
authorMichal Bloch <m.bloch@samsung.com>
Mon, 9 Jun 2025 19:58:58 +0000 (21:58 +0200)
committerMichal Bloch <m.bloch@samsung.com>
Tue, 10 Jun 2025 19:00:39 +0000 (21:00 +0200)
Change-Id: Ie75bd8c118d2ad5ba4eac485974501ebe52a0819

src/library/src/lib.c
src/service/sessiond.service
src/service/src/main.cpp

index 3e589c3f49ccd08f53c6800ada832d33e1f7e4ef..f4bda6e64714a27486512f2473667984be44afe0 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE. */
 
+#define _GNU_SOURCE
+
+#include <stdio.h>
 #include <assert.h>
+#include <fcntl.h>
 #include <gio/gio.h>
 #include <tizen.h>
 #include <ctype.h>
@@ -1081,10 +1085,51 @@ EXPORT_API void subsession_free_user_list(subsession_user_t *user_list)
        free(user_list);
 }
 
+static int get_current_from_file(int session_uid, subsession_user_t user)
+{
+       __attribute__((cleanup(free_ptr))) char *main_dir = NULL;
+       const int r = get_main_dir(&main_dir, session_uid);
+       if (r != 0)
+               return r;
+
+       __attribute__((cleanup(free_ptr))) char *last_file = NULL;
+       if (asprintf(&last_file, "%s/.last_subsession_name", main_dir) < 0)
+               return SUBSESSION_ERROR_OUT_OF_MEMORY;
+       if (!last_file)
+               return SUBSESSION_ERROR_OUT_OF_MEMORY;
+
+       const int fd = open(last_file, O_RDONLY);
+       if (fd == -1) {
+               if (errno == ENOENT) {
+                       subsession_user_copy(user, SUBSESSION_INITIAL_SID);
+                       return SUBSESSION_ERROR_NONE;
+               } else {
+                       return SUBSESSION_ERROR_IO_ERROR;
+               }
+       }
+
+       const int bytes_read = read(fd, user, SUBSESSION_USER_MAXLEN - 1);
+       close(fd);
+
+       if (bytes_read < 0)
+               return SUBSESSION_ERROR_IO_ERROR;
+
+       user[bytes_read] = 0;
+       return SUBSESSION_ERROR_NONE;
+}
+
 EXPORT_API int subsession_get_current_user(int session_uid, subsession_user_t user)
 {
        return_if(session_uid_is_not_valid(session_uid, current_user_ptr_is_null(user)))
 
+       /* "Fallback" for when the daemon is not yet alive, e.g.
+        * at early boot. It's actually much faster so would have
+        * been a good idea to use regardless, but the requirement
+        * is to prefer D-Bus when the daemon is alive. */
+       if (access("/run/sessiond.pid", F_OK) != 0)
+               return get_current_from_file(session_uid, user);
+
+       // "normal" D-Bus path
        g_autoptr(GVariant) out = NULL;
        int ret = method_call_sync(dbus_method_call.GetCurrentUser,
                        g_variant_new("(i)", session_uid),
index 2a5745c3318f76dd93f1fc9236495e4663e195b0..046c91970f5b3b13b3e161886a02c2cae55f0f90 100644 (file)
@@ -13,6 +13,7 @@ SmackProcessLabel=System::Privileged
 ExecStart=/usr/bin/sessiond
 Restart=on-failure
 MemoryMax=20M
+PIDFile=/run/sessiond.pid
 
 [Install]
 WantedBy=delayed.target
index 8eae03bf1d8bf6160fe72bbc80afbeb8ff60e280..cd1eb27ac80a6e8fa99bcd508e3518452223e882 100644 (file)
 
 #include "main_context.hpp"
 #include "main_restore.hpp"
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <iostream>
 #include <stdexcept>
 
 std::unique_ptr <sessiond_context> g_sessiond_context;
@@ -40,6 +45,7 @@ int main(int argc, char **argv) try {
        } else {
                g_sessiond_context = std::make_unique <sessiond_context> ();
                restore_all_user_sessions(false);
+               std::ofstream("/run/sessiond.pid", std::ios::out | std::ios::trunc) << getpid();
                g_sessiond_context->run();
        }
 } catch (const std::exception &ex) {