From 681172a999466125868e6c209910858954cf6534 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Wed, 22 Jan 2020 11:15:19 -0600 Subject: [PATCH] storage: Add ability to preserve times We use the mtime on the network profile as the 'Last Connected Time'. When we update any property and sync the file to disk, the mtime was not preserved (since we were creating a new temporary file instead of modifying the old one). This led to LastConnectedTime property change being emitted / updated incorrectly when a writable property on the KnownNetwork interface was updated. --- src/hotspot.c | 2 +- src/storage.c | 18 +++++++++++++++--- src/storage.h | 5 +++-- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/hotspot.c b/src/hotspot.c index fb75ef13..e0252753 100644 --- a/src/hotspot.c +++ b/src/hotspot.c @@ -112,7 +112,7 @@ static void hotspot_network_sync(struct network_info *info, super); data = l_settings_to_data(settings, &length); - write_file(data, length, "%s", config->filename); + write_file(data, length, true, "%s", config->filename); l_free(data); } diff --git a/src/storage.c b/src/storage.c index 66e6b49e..a075d31d 100644 --- a/src/storage.c +++ b/src/storage.c @@ -120,7 +120,7 @@ ssize_t read_file(void *buffer, size_t len, const char *path_fmt, ...) * file with a temporary name and when closed, it is renamed to the * specified name (@path_fmt+args). */ -ssize_t write_file(const void *buffer, size_t len, +ssize_t write_file(const void *buffer, size_t len, bool preserve_times, const char *path_fmt, ...) { va_list ap; @@ -150,6 +150,18 @@ ssize_t write_file(const void *buffer, size_t len, goto error_write; } + if (preserve_times) { + struct stat st; + + if (stat(path, &st) == 0) { + struct timespec times[2]; + + times[0] = st.st_atim; + times[1] = st.st_mtim; + utimensat(0, tmp_path, times, 0); + } + } + /* * Now that the file contents are written, rename to the real * file name; this way we are uniquely sure that the whole @@ -372,7 +384,7 @@ void storage_network_sync(enum security type, const char *ssid, path = storage_get_network_file_path(type, ssid); data = l_settings_to_data(settings, &length); - write_file(data, length, "%s", path); + write_file(data, length, true, "%s", path); l_free(data); l_free(path); } @@ -420,7 +432,7 @@ void storage_known_frequencies_sync(struct l_settings *known_freqs) known_freq_file_path = storage_get_path("/%s", KNOWN_FREQ_FILENAME); data = l_settings_to_data(known_freqs, &len); - write_file(data, len, "%s", known_freq_file_path); + write_file(data, len, false, "%s", known_freq_file_path); l_free(data); l_free(known_freq_file_path); diff --git a/src/storage.h b/src/storage.h index 891bb771..80b63c53 100644 --- a/src/storage.h +++ b/src/storage.h @@ -28,8 +28,9 @@ enum security; ssize_t read_file(void *buffer, size_t len, const char *path_fmt, ...) __attribute__((format(printf, 3, 4))); -ssize_t write_file(const void *buffer, size_t len, const char *path_fmt, ...) - __attribute__((format(printf, 3, 4))); +ssize_t write_file(const void *buffer, size_t len, bool preserve_times, + const char *path_fmt, ...) + __attribute__((format(printf, 4, 5))); bool storage_create_dirs(void); void storage_cleanup_dirs(void);