From df2b472cd95d0aba99451b991da1af8c8f9d4e59 Mon Sep 17 00:00:00 2001 From: Cyril Cleaud Date: Thu, 26 Jun 2014 22:59:17 -0700 Subject: [PATCH] Add umask and rename compatibility wrappers for Windows umask() doesn't exist on Windows and is thus a no-op. rename() only works if the destination doesn't already exist, so we must unlink before renaming. --- commands.cpp | 2 +- key.cpp | 4 ++-- util-unix.cpp | 16 +++++++++++++--- util-win32.cpp | 13 +++++++++++++ util.hpp | 3 +++ 5 files changed, 32 insertions(+), 6 deletions(-) diff --git a/commands.cpp b/commands.cpp index 9519eb1..5472766 100644 --- a/commands.cpp +++ b/commands.cpp @@ -765,7 +765,7 @@ int migrate_key (int argc, char** argv) return 1; } - if (rename(new_key_file_name.c_str(), key_file_name) == -1) { + if (util_rename(new_key_file_name.c_str(), key_file_name) == -1) { std::clog << "Error: " << key_file_name << ": " << strerror(errno) << std::endl; unlink(new_key_file_name.c_str()); return 1; diff --git a/key.cpp b/key.cpp index 508ff8d..05e059c 100644 --- a/key.cpp +++ b/key.cpp @@ -134,9 +134,9 @@ bool Key_file::load_from_file (const char* key_file_name) bool Key_file::store_to_file (const char* key_file_name) const { - mode_t old_umask = umask(0077); // make sure key file is protected (TODO: Windows compat) + mode_t old_umask = util_umask(0077); // make sure key file is protected std::ofstream key_file_out(key_file_name, std::fstream::binary); - umask(old_umask); + util_umask(old_umask); if (!key_file_out) { return false; } diff --git a/util-unix.cpp b/util-unix.cpp index 7f92a58..1224e66 100644 --- a/util-unix.cpp +++ b/util-unix.cpp @@ -69,14 +69,14 @@ void temp_fstream::open (std::ios_base::openmode mode) char* path = &path_buffer[0]; std::strcpy(path, tmpdir); std::strcpy(path + tmpdir_len, "/git-crypt.XXXXXX"); - mode_t old_umask = umask(0077); + mode_t old_umask = util_umask(0077); int fd = mkstemp(path); if (fd == -1) { int mkstemp_errno = errno; - umask(old_umask); + util_umask(old_umask); throw System_error("mkstemp", "", mkstemp_errno); } - umask(old_umask); + util_umask(old_umask); std::fstream::open(path, mode); if (!std::fstream::is_open()) { unlink(path); @@ -277,3 +277,13 @@ bool successful_exit (int status) static void init_std_streams_platform () { } + +mode_t util_umask (mode_t mode) +{ + return umask(mode); +} + +int util_rename (const char* from, const char* to) +{ + return rename(from, to); +} diff --git a/util-win32.cpp b/util-win32.cpp index e852e52..b0d20d1 100644 --- a/util-win32.cpp +++ b/util-win32.cpp @@ -325,3 +325,16 @@ static void init_std_streams_platform () _setmode(_fileno(stdin), _O_BINARY); _setmode(_fileno(stdout), _O_BINARY); } + +mode_t util_umask (mode_t mode) +{ + // Not available in Windows and function not always defined in Win32 environments + return 0; +} + +int util_rename (const char* from, const char* to) +{ + // On Windows OS, it is necessary to ensure target file doesn't exist + unlink(to); + return rename(from, to); +} diff --git a/util.hpp b/util.hpp index 7cae193..cf23771 100644 --- a/util.hpp +++ b/util.hpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -69,6 +70,8 @@ void store_be32 (unsigned char*, uint32_t); bool read_be32 (std::istream& in, uint32_t&); void write_be32 (std::ostream& out, uint32_t); void init_std_streams (); +mode_t util_umask (mode_t); +int util_rename (const char*, const char*); #endif