logind: port logind state files to fopen_tmpfile_linkable()

This replaces use of fopen_temporary() with fopen_tmpfile_linkable() +
flink_tmpfile(). This both shortens the code and means we use O_TMPFILE
for installing these files, which is always good.

No change in behaviour otherwise.
This commit is contained in:
Lennart Poettering
2025-05-19 10:15:25 +02:00
parent e27333b2cc
commit 019c8ea26a
4 changed files with 52 additions and 99 deletions

View File

@@ -89,21 +89,22 @@ Inhibitor* inhibitor_free(Inhibitor *i) {
}
static int inhibitor_save(Inhibitor *i) {
_cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(i);
r = mkdir_safe_label("/run/systemd/inhibit", 0755, 0, 0, MKDIR_WARN_MODE);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to create /run/systemd/inhibit/: %m");
r = fopen_temporary(i->state_file, &f, &temp_path);
_cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
r = fopen_tmpfile_linkable(i->state_file, O_WRONLY|O_CLOEXEC, &temp_path, &f);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to create state file '%s': %m", i->state_file);
(void) fchmod(fileno(f), 0644);
if (fchmod(fileno(f), 0644) < 0)
return log_error_errno(errno, "Failed to set access mode for state file '%s' to 0644: %m", i->state_file);
fprintf(f,
"# This is private data. Do not parse.\n"
@@ -120,10 +121,8 @@ static int inhibitor_save(Inhibitor *i) {
_cleanup_free_ char *cc = NULL;
cc = cescape(i->who);
if (!cc) {
r = -ENOMEM;
goto fail;
}
if (!cc)
return log_oom();
fprintf(f, "WHO=%s\n", cc);
}
@@ -132,10 +131,8 @@ static int inhibitor_save(Inhibitor *i) {
_cleanup_free_ char *cc = NULL;
cc = cescape(i->why);
if (!cc) {
r = -ENOMEM;
goto fail;
}
if (!cc)
return log_oom();
fprintf(f, "WHY=%s\n", cc);
}
@@ -143,22 +140,12 @@ static int inhibitor_save(Inhibitor *i) {
if (i->fifo_path)
fprintf(f, "FIFO=%s\n", i->fifo_path);
r = fflush_and_check(f);
r = flink_tmpfile(f, temp_path, i->state_file, LINK_TMPFILE_REPLACE);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to move '%s' into place: %m", i->state_file);
if (rename(temp_path, i->state_file) < 0) {
r = -errno;
goto fail;
}
temp_path = mfree(temp_path);
temp_path = mfree(temp_path); /* disarm auto-destroy: temporary file does not exist anymore */
return 0;
fail:
(void) unlink(i->state_file);
return log_error_errno(r, "Failed to save inhibit data %s: %m", i->state_file);
}
static int bus_manager_send_inhibited_change(Inhibitor *i) {

View File

@@ -88,8 +88,6 @@ Seat* seat_free(Seat *s) {
}
int seat_save(Seat *s) {
_cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(s);
@@ -99,13 +97,16 @@ int seat_save(Seat *s) {
r = mkdir_safe_label("/run/systemd/seats", 0755, 0, 0, MKDIR_WARN_MODE);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to create /run/systemd/seats/: %m");
r = fopen_temporary(s->state_file, &f, &temp_path);
_cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
r = fopen_tmpfile_linkable(s->state_file, O_WRONLY|O_CLOEXEC, &temp_path, &f);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to create state file '%s': %m", s->state_file);
(void) fchmod(fileno(f), 0644);
if (fchmod(fileno(f), 0644) < 0)
return log_error_errno(errno, "Failed to set access mode for state file '%s' to 0644: %m", s->state_file);
fprintf(f,
"# This is private data. Do not parse.\n"
@@ -144,21 +145,12 @@ int seat_save(Seat *s) {
i->sessions_by_seat_next ? ' ' : '\n');
}
r = fflush_and_check(f);
r = flink_tmpfile(f, temp_path, s->state_file, LINK_TMPFILE_REPLACE);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to move '%s' into place: %m", s->state_file);
if (rename(temp_path, s->state_file) < 0) {
r = -errno;
goto fail;
}
temp_path = mfree(temp_path);
temp_path = mfree(temp_path); /* disarm auto-destroy: temporary file does not exist anymore */
return 0;
fail:
(void) unlink(s->state_file);
return log_error_errno(r, "Failed to save seat data %s: %m", s->state_file);
}
int seat_load(Seat *s) {

View File

@@ -276,8 +276,6 @@ static void session_save_devices(Session *s, FILE *f) {
}
int session_save(Session *s) {
_cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(s);
@@ -290,13 +288,16 @@ int session_save(Session *s) {
r = mkdir_safe_label("/run/systemd/sessions", 0755, 0, 0, MKDIR_WARN_MODE);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to create /run/systemd/sessions/: %m");
r = fopen_temporary(s->state_file, &f, &temp_path);
_cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
r = fopen_tmpfile_linkable(s->state_file, O_WRONLY|O_CLOEXEC, &temp_path, &f);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to create state file '%s': %m", s->state_file);
(void) fchmod(fileno(f), 0644);
if (fchmod(fileno(f), 0644) < 0)
return log_error_errno(errno, "Failed to set access mode for state file '%s' to 0644: %m", s->state_file);
fprintf(f,
"# This is private data. Do not parse.\n"
@@ -345,10 +346,8 @@ int session_save(Session *s) {
_cleanup_free_ char *escaped = NULL;
escaped = cescape(s->remote_host);
if (!escaped) {
r = -ENOMEM;
goto fail;
}
if (!escaped)
return log_oom();
fprintf(f, "REMOTE_HOST=%s\n", escaped);
}
@@ -357,10 +356,8 @@ int session_save(Session *s) {
_cleanup_free_ char *escaped = NULL;
escaped = cescape(s->remote_user);
if (!escaped) {
r = -ENOMEM;
goto fail;
}
if (!escaped)
return log_oom();
fprintf(f, "REMOTE_USER=%s\n", escaped);
}
@@ -369,10 +366,8 @@ int session_save(Session *s) {
_cleanup_free_ char *escaped = NULL;
escaped = cescape(s->service);
if (!escaped) {
r = -ENOMEM;
goto fail;
}
if (!escaped)
return log_oom();
fprintf(f, "SERVICE=%s\n", escaped);
}
@@ -381,10 +376,8 @@ int session_save(Session *s) {
_cleanup_free_ char *escaped = NULL;
escaped = cescape(s->desktop);
if (!escaped) {
r = -ENOMEM;
goto fail;
}
if (!escaped)
return log_oom();
fprintf(f, "DESKTOP=%s\n", escaped);
}
@@ -413,22 +406,12 @@ int session_save(Session *s) {
session_save_devices(s, f);
}
r = fflush_and_check(f);
r = flink_tmpfile(f, temp_path, s->state_file, LINK_TMPFILE_REPLACE);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to move '%s' into place: %m", s->state_file);
if (rename(temp_path, s->state_file) < 0) {
r = -errno;
goto fail;
}
temp_path = mfree(temp_path);
temp_path = mfree(temp_path); /* disarm auto-destroy: temporary file does not exist anymore */
return 0;
fail:
(void) unlink(s->state_file);
return log_error_errno(r, "Failed to save session data %s: %m", s->state_file);
}
static int session_load_devices(Session *s, const char *devices) {

View File

@@ -144,8 +144,6 @@ User *user_free(User *u) {
}
static int user_save_internal(User *u) {
_cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(u);
@@ -153,13 +151,16 @@ static int user_save_internal(User *u) {
r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0, MKDIR_WARN_MODE);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to create /run/systemd/users/: %m");
r = fopen_temporary(u->state_file, &f, &temp_path);
_cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL;
r = fopen_tmpfile_linkable(u->state_file, O_WRONLY|O_CLOEXEC, &temp_path, &f);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to create state file '%s': %m", u->state_file);
(void) fchmod(fileno(f), 0644);
if (fchmod(fileno(f), 0644) < 0)
return log_error_errno(errno, "Failed to set access mode for state file '%s' to 0644: %m", u->state_file);
fprintf(f,
"# This is private data. Do not parse.\n"
@@ -282,22 +283,12 @@ static int user_save_internal(User *u) {
fputc('\n', f);
}
r = fflush_and_check(f);
r = flink_tmpfile(f, temp_path, u->state_file, LINK_TMPFILE_REPLACE);
if (r < 0)
goto fail;
return log_error_errno(r, "Failed to move '%s' into place: %m", u->state_file);
if (rename(temp_path, u->state_file) < 0) {
r = -errno;
goto fail;
}
temp_path = mfree(temp_path);
temp_path = mfree(temp_path); /* disarm auto-destroy: temporary file does not exist anymore */
return 0;
fail:
(void) unlink(u->state_file);
return log_error_errno(r, "Failed to save user data %s: %m", u->state_file);
}
int user_save(User *u) {