From 770da79cf39e41772bc46dfe61f671cd7a1f5de8 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Wed, 18 Jan 2023 21:46:57 +0300 Subject: [PATCH] daemon: check whether log file is regular and may be flushed (#4612) --- daemon/daemon.cc | 10 ++++++---- daemon/daemon.h | 1 + libtransmission/file-posix.cc | 17 ++++++++++++++++- libtransmission/file-win32.cc | 15 +++++++++++++++ libtransmission/file.h | 3 +++ 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/daemon/daemon.cc b/daemon/daemon.cc index ae4dd031a..8256b91c1 100644 --- a/daemon/daemon.cc +++ b/daemon/daemon.cc @@ -172,6 +172,7 @@ bool tr_daemon::reopen_log_file(char const* filename) } logfile_ = new_log_file; + logfile_flush_ = tr_sys_file_flush_possible(logfile_); if (old_log_file != TR_BAD_SYS_FILE) { @@ -362,7 +363,7 @@ static void printMessage( #endif } -static void pumpLogMessages(tr_sys_file_t file) +static void pumpLogMessages(tr_sys_file_t file, bool flush) { tr_log_message* list = tr_logGetQueue(); @@ -371,7 +372,7 @@ static void pumpLogMessages(tr_sys_file_t file) printMessage(file, l->level, l->name, l->message, l->file, l->line); } - if (file != TR_BAD_SYS_FILE) + if (flush && file != TR_BAD_SYS_FILE) { tr_sys_file_flush(file); } @@ -396,7 +397,7 @@ void tr_daemon::report_status(void) void tr_daemon::periodic_update(void) { - pumpLogMessages(logfile_); + pumpLogMessages(logfile_, logfile_flush_); report_status(); } @@ -852,7 +853,7 @@ CLEANUP: tr_sessionSaveSettings(my_session_, cdir, &settings_); tr_sessionClose(my_session_); - pumpLogMessages(logfile_); + pumpLogMessages(logfile_, logfile_flush_); printf(" done.\n"); /* shutdown */ @@ -899,6 +900,7 @@ bool tr_daemon::init(int argc, char const* const argv[], bool* foreground, int* if (*foreground && logfile_ == TR_BAD_SYS_FILE) { logfile_ = tr_sys_file_get_std(TR_STD_SYS_FILE_ERR); + logfile_flush_ = tr_sys_file_flush_possible(logfile_); } if (!loaded) diff --git a/daemon/daemon.h b/daemon/daemon.h index 522d8e926..1c7d13d44 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -47,6 +47,7 @@ private: bool seen_hup_ = false; std::string config_dir_; tr_variant settings_ = {}; + bool logfile_flush_ = false; tr_session* my_session_ = nullptr; char const* log_file_name_ = nullptr; struct event_base* ev_base_ = nullptr; diff --git a/libtransmission/file-posix.cc b/libtransmission/file-posix.cc index 8946b15ee..9b3fcb528 100644 --- a/libtransmission/file-posix.cc +++ b/libtransmission/file-posix.cc @@ -798,7 +798,7 @@ bool tr_sys_file_flush(tr_sys_file_t handle, tr_error** error) { TR_ASSERT(handle != TR_BAD_SYS_FILE); - bool const ret = (isatty(handle) != 0) || (fsync(handle) != -1); + bool const ret = (fsync(handle) != -1); if (!ret) { @@ -808,6 +808,21 @@ bool tr_sys_file_flush(tr_sys_file_t handle, tr_error** error) return ret; } +bool tr_sys_file_flush_possible(tr_sys_file_t handle, tr_error** error) +{ + TR_ASSERT(handle != TR_BAD_SYS_FILE); + + struct stat statbuf; + + if (fstat(handle, &statbuf) != 0) + { + set_system_error(error, errno); + return false; + } + + return S_ISREG(statbuf.st_mode); +} + bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error** error) { TR_ASSERT(handle != TR_BAD_SYS_FILE); diff --git a/libtransmission/file-win32.cc b/libtransmission/file-win32.cc index ef1852abd..48eb512d1 100644 --- a/libtransmission/file-win32.cc +++ b/libtransmission/file-win32.cc @@ -1106,6 +1106,21 @@ bool tr_sys_file_flush(tr_sys_file_t handle, tr_error** error) return ret; } +bool tr_sys_file_flush_possible(tr_sys_file_t handle, tr_error** error) +{ + TR_ASSERT(handle != TR_BAD_SYS_FILE); + + DWORD type = GetFileType(handle); + + if (type == FILE_TYPE_UNKNOWN) + { + set_system_error(error, GetLastError()); + return false; + } + + return type == FILE_TYPE_DISK; +} + bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error** error) { TR_ASSERT(handle != TR_BAD_SYS_FILE); diff --git a/libtransmission/file.h b/libtransmission/file.h index 575821371..6d19340f2 100644 --- a/libtransmission/file.h +++ b/libtransmission/file.h @@ -445,6 +445,9 @@ bool tr_sys_file_write_at( */ bool tr_sys_file_flush(tr_sys_file_t handle, struct tr_error** error = nullptr); +/* @brief Check whether `handle` may be flushed via `tr_sys_file_flush()`. */ +bool tr_sys_file_flush_possible(tr_sys_file_t handle, struct tr_error** error = nullptr); + /** * @brief Portability wrapper for `ftruncate()`. *