From 374db6aebec2a008538c7708305b9be01000c013 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 22 Jul 2017 14:15:35 +0200 Subject: Add touch_file() filesystem function --- libbutl/filesystem.cxx | 29 +++++++++++++++++++++++++++++ libbutl/filesystem.hxx | 8 ++++++++ 2 files changed, 37 insertions(+) diff --git a/libbutl/filesystem.cxx b/libbutl/filesystem.cxx index 70597b9..7ba5275 100644 --- a/libbutl/filesystem.cxx +++ b/libbutl/filesystem.cxx @@ -6,6 +6,7 @@ #ifndef _WIN32 # include // rename() +# include // utime() # include // struct dirent, *dir() # include // symlink(), link(), stat(), rmdir(), unlink() # include // utimes() @@ -18,6 +19,7 @@ # include // _mkdir(), _rmdir() # include // _stat # include // _stat(), S_I* +# include // _utime() # ifdef _MSC_VER // Unlikely to be fixed in newer versions. # define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) @@ -153,6 +155,33 @@ namespace butl } #endif + bool + touch_file (const path& p, bool create) + { + if (file_exists (p)) + { +#ifndef _WIN32 + if (utime (p.string ().c_str (), nullptr) == -1) +#else + if (_utime (p.string ().c_str (), nullptr) == -1) +#endif + throw_generic_error (errno); + + return false; + } + + if (create && !entry_exists (p)) + { + // Assuming the file access and modification times are set to the + // current time automatically. + // + fdopen (p, fdopen_mode::out | fdopen_mode::create); + return true; + } + + throw_generic_error (ENOENT); // Does not exist or not a file. + } + mkdir_status #ifndef _WIN32 try_mkdir (const dir_path& p, mode_t m) diff --git a/libbutl/filesystem.hxx b/libbutl/filesystem.hxx index 9bf6f0c..ef1b22b 100644 --- a/libbutl/filesystem.hxx +++ b/libbutl/filesystem.hxx @@ -104,6 +104,14 @@ namespace butl bool file_empty (const path&); + // Set the file access and modification times to the current time. If the + // file does not exist and create is true, create it and fail otherwise. + // Return true if the file was created and false otherwise. Errors are + // reported by throwing std::system_error. + // + LIBBUTL_SYMEXPORT bool + touch_file (const path&, bool create = true); + // Try to create a directory unless it already exists. If you expect // the directory to exist and performance is important, then you // should first call dir_exists() above since that's what this -- cgit v1.1