diff --git a/include/spdlog/sinks/rotating_file_sink-inl.h b/include/spdlog/sinks/rotating_file_sink-inl.h index d715ebf3..ba2999e9 100644 --- a/include/spdlog/sinks/rotating_file_sink-inl.h +++ b/include/spdlog/sinks/rotating_file_sink-inl.h @@ -25,14 +25,20 @@ namespace sinks { template SPDLOG_INLINE rotating_file_sink::rotating_file_sink( - filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open) + filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open, uid_t uid, gid_t gid) : base_filename_(std::move(base_filename)) , max_size_(max_size) , max_files_(max_files) + , uid_ (uid) + , gid_ (gid) { file_helper_.open(calc_filename(base_filename_, 0)); + current_size_ = file_helper_.size(); // expensive. called only once - if (rotate_on_open && current_size_ > 0) + + set_file_ownership(calc_filename(base_filename_, 0)); + + if (rotate_on_open && current_size_ > 0) { rotate_(); } @@ -110,11 +116,16 @@ SPDLOG_INLINE void rotating_file_sink::rotate_() { file_helper_.reopen(true); // truncate the log file anyway to prevent it to grow beyond its limit! current_size_ = 0; - throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno); + auto last_error = errno; + set_file_ownership(calc_filename(base_filename_, 0)); + throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), last_error); } } + + set_file_ownership(target); } file_helper_.reopen(true); + set_file_ownership(calc_filename(base_filename_, 0)); } // delete the target if exists, and rename the src file to target @@ -126,6 +137,14 @@ SPDLOG_INLINE bool rotating_file_sink::rename_file_(const filename_t &src (void)details::os::remove(target_filename); return details::os::rename(src_filename, target_filename) == 0; } +template +SPDLOG_INLINE void rotating_file_sink::set_file_ownership(filename_t filename) +{ + if (chown(filename.data(), uid_, gid_) < 0) { + throw spdlog_ex( + "set_file_ownership: failed changing file ownership " + details::os::filename_to_str(filename), errno); + } +} } // namespace sinks } // namespace spdlog diff --git a/include/spdlog/sinks/rotating_file_sink.h b/include/spdlog/sinks/rotating_file_sink.h index e1e85a7d..db506c4a 100644 --- a/include/spdlog/sinks/rotating_file_sink.h +++ b/include/spdlog/sinks/rotating_file_sink.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include #include @@ -22,7 +23,7 @@ template class rotating_file_sink final : public base_sink { public: - rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false); + rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false, uid_t uid = -1, gid_t gid = -1); static filename_t calc_filename(const filename_t &filename, std::size_t index); filename_t filename(); @@ -42,11 +43,15 @@ private: // return true on success, false otherwise. bool rename_file_(const filename_t &src_filename, const filename_t &target_filename); + void set_file_ownership(filename_t filename); + filename_t base_filename_; std::size_t max_size_; std::size_t max_files_; std::size_t current_size_; details::file_helper file_helper_; + uid_t uid_; + gid_t gid_; }; using rotating_file_sink_mt = rotating_file_sink; @@ -60,9 +65,9 @@ using rotating_file_sink_st = rotating_file_sink; template inline std::shared_ptr rotating_logger_mt( - const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false) + const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false, uid_t uid = -1, gid_t gid = -1) { - return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open); + return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open, uid, gid); } template