aboutsummaryrefslogtreecommitdiff
path: root/butl/filesystem.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-08-29 18:51:07 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-08-29 18:51:07 +0200
commit807bb530ecf6cde6c13956a20f64db32e86b892e (patch)
treea8e3b942717b17b8b4bbb6c39c8def9c1f5406fa /butl/filesystem.cxx
parent135a0bcb957dc836c425f51eeeeae4148092fdf8 (diff)
Add flag to file_exists() not to follow symlinks
Diffstat (limited to 'butl/filesystem.cxx')
-rw-r--r--butl/filesystem.cxx23
1 files changed, 19 insertions, 4 deletions
diff --git a/butl/filesystem.cxx b/butl/filesystem.cxx
index 5584e00..a47140d 100644
--- a/butl/filesystem.cxx
+++ b/butl/filesystem.cxx
@@ -34,16 +34,27 @@ using namespace std;
namespace butl
{
+#ifndef _WIN32
bool
- file_exists (const char* p)
+ file_exists (const char* p, bool fl)
{
-#ifndef _WIN32
struct stat s;
- if (stat (p, &s) != 0)
+ if ((fl ? stat (p, &s) : lstat (p, &s)) != 0)
+ {
+ if (errno == ENOENT || errno == ENOTDIR)
+ return false;
+ else
+ throw system_error (errno, system_category ());
+ }
+
+ return S_ISREG (s.st_mode) || (!fl && S_ISLNK (s.st_mode));
+ }
#else
+ bool
+ file_exists (const char* p, bool)
+ {
struct _stat s;
if (_stat (p, &s) != 0)
-#endif
{
if (errno == ENOENT || errno == ENOTDIR)
return false;
@@ -53,6 +64,7 @@ namespace butl
return S_ISREG (s.st_mode);
}
+#endif
bool
dir_exists (const char* p)
@@ -172,6 +184,9 @@ namespace butl
if (_unlink (p.string ().c_str ()) != 0)
#endif
{
+ // Strangely on Linux unlink() removes a dangling symlink but returns
+ // ENOENT.
+ //
if (errno == ENOENT || errno == ENOTDIR)
r = rmfile_status::not_exist;
else if (!ignore_error)