close(fd);
}
-static void restore_user_session(const fs::path& user_home_dir)
+static void restore_user_session(const fs::path& username, int uid)
{
- /* Somewhere below we get username back from uid,
- * so it would be good to refactor it so as to be
- * able to take either arg and avoid the syscall. */
- const auto username = user_home_dir.filename();
- int uid = -1;
-
std::string last_subsession;
try {
- uid = OS::get_uid_from_name(username.native());
std::ifstream(get_last_subsession_path_by_user_id(uid), std::ios::in) >> last_subsession;
} catch (const std::exception &ex) {
- LOGE("Could not retrieve last subsession of user %s (uid %d)", username.c_str(), uid);
-
- /* Don't rethrow since the most common errors are fine:
- * - name doesn't necessarily map to an existing UID,
- * this can happen e.g. when you install debug rpm
- * packages which leaves some build artifacts under
- * the `abuild` folder which isn't a user on target.
- * - at first boot, the last subsession file won't exist. */
+ LOGE("Could not retrieve last subsession of user %s (uid %d): %s", username.c_str(), uid, ex.what());
+
+ /* At first boot, the last subsession file won't exist.
+ * This is common and fine - don't rethrow. */
return;
}
continue;
const auto& username = entry.path().filename();
- LOGI("Restoring last session for user %s", username.c_str());
- restore_user_session(entry.path());
+ int uid;
+ try {
+ /* This has to be under a try clause because user
+ * name doesn't necessarily map to an existing UID,
+ * this can happen e.g. when you install debug rpm
+ * packages which leaves some build artifacts under
+ * the `abuild` folder which isn't a user on target. */
+ uid = OS::get_uid_from_name(username.native());
+ } catch (const std::exception &ex) {
+ LOGW("Could not get uid of user '%s', skipping", username.c_str());
+ continue;
+ }
+
+ LOGI("Restoring last session for user %s (uid %d)", username.c_str(), uid);
+ restore_user_session(username, uid);
}
}