Add session.umask.set to configure session file permissions.

This commit is contained in:
Copilot
2026-10-20 18:32:32 +09:00
committed by GitHub
parent 8cab343a82
commit d316b21cf0
8 changed files with 70 additions and 10 deletions
+12 -5
View File
@@ -5,6 +5,7 @@
#include <cerrno>
#include <fcntl.h>
#include <fstream>
#include <sys/stat.h>
#include <unistd.h>
#include <torrent/exceptions.h>
#include <torrent/object.h>
@@ -123,7 +124,7 @@ is_correct_format(const std::string& f) {
}
void
save_stream(const std::string& path, bool use_fsyncdisk, const std::stringstream& stream) {
save_stream(const std::string& path, bool use_fsyncdisk, mode_t file_mode, const std::stringstream& stream) {
// Remove any leftover temporary file first so that O_EXCL only ever fails on
// an entry that appeared after the unlink, and O_NOFOLLOW keeps a symlink
// planted in the session directory from redirecting the write.
@@ -136,6 +137,12 @@ save_stream(const std::string& path, bool use_fsyncdisk, const std::stringstream
if (fd < 0)
throw torrent::storage_error("failed to open file for writing : " + path);
// open() applies the process umask, so set the configured mode explicitly.
if (file_mode != 0 && ::fchmod(fd, file_mode) == -1) {
::close(fd);
throw torrent::storage_error("failed to set file permissions : " + path);
}
const auto data = stream.view();
std::size_t remaining = data.size();
const char* cursor = data.data();
@@ -196,7 +203,7 @@ sync_directory_of(const std::string& path) {
} // namespace anonymous
void
DownloadStorer::save_and_move_streams(const std::string& path, bool use_fsyncdisk,
DownloadStorer::save_and_move_streams(const std::string& path, bool use_fsyncdisk, mode_t file_mode,
const std::stringstream* torrent_stream,
const std::stringstream* rtorrent_stream,
const std::stringstream* libtorrent_stream) {
@@ -205,10 +212,10 @@ DownloadStorer::save_and_move_streams(const std::string& path, bool use_fsyncdis
auto rtorrent_path = path + ".rtorrent";
if (torrent_stream)
save_stream(torrent_path + ".new", use_fsyncdisk, *torrent_stream);
save_stream(torrent_path + ".new", use_fsyncdisk, file_mode, *torrent_stream);
save_stream(libtorrent_path + ".new", use_fsyncdisk, *libtorrent_stream);
save_stream(rtorrent_path + ".new", use_fsyncdisk, *rtorrent_stream);
save_stream(libtorrent_path + ".new", use_fsyncdisk, file_mode, *libtorrent_stream);
save_stream(rtorrent_path + ".new", use_fsyncdisk, file_mode, *rtorrent_stream);
if (torrent_stream) {
if (::rename((torrent_path + ".new").c_str(), torrent_path.c_str()) == -1)