aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbutl/filesystem.cxx29
-rw-r--r--libbutl/filesystem.hxx8
2 files changed, 37 insertions, 0 deletions
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 <stdio.h> // rename()
+# include <utime.h> // utime()
# include <dirent.h> // struct dirent, *dir()
# include <unistd.h> // symlink(), link(), stat(), rmdir(), unlink()
# include <sys/time.h> // utimes()
@@ -18,6 +19,7 @@
# include <direct.h> // _mkdir(), _rmdir()
# include <sys/types.h> // _stat
# include <sys/stat.h> // _stat(), S_I*
+# include <sys/utime.h> // _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