]> git.tdb.fi Git - libs/core.git/blobdiff - source/fs/stat.cpp
Change stat functions so that it's again possible to determine file existence
[libs/core.git] / source / fs / stat.cpp
index 245dd4ea9e05e4510768343ad8a5ff62a066313f..716a7d6a4f82707587aed2a9b452aa4bde87715c 100644 (file)
@@ -2,6 +2,8 @@
 #include <windows.h>
 #include <aclapi.h>
 #else
+#define _FILE_OFFSET_BITS 64
+#include <cerrno>
 #include <sys/stat.h>
 #include <grp.h>
 #include <pwd.h>
@@ -45,6 +47,7 @@ struct Stat::Private
 Stat Stat::Private::from_struct_stat(const struct stat &st)
 {
        Stat result;
+       result.exists = true;
        if(S_ISREG(st.st_mode))
                result.type = REGULAR;
        else if(S_ISDIR(st.st_mode))
@@ -78,6 +81,7 @@ Stat Stat::Private::from_struct_stat(const struct stat &st)
 #endif
 
 Stat::Stat():
+       exists(false),
        type(UNKNOWN),
        size(0),
        alloc_size(0)
@@ -87,7 +91,7 @@ Stat Stat::stat(const Path &path)
 {
 #ifdef WIN32
        HANDLE handle;
-       handle = CreateFile(path.str().c_str(), 0, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+       handle = CreateFile(path.str().c_str(), 0, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
        if(handle==INVALID_HANDLE_VALUE)
                throw system_error("CreateFile");
 
@@ -109,16 +113,18 @@ Stat Stat::stat(const Path &path)
        result.mtime = Time::TimeStamp(Time::filetime_to_rawtime(info.ftLastWriteTime));
 
        PSECURITY_DESCRIPTOR sec_desc;
-       PSID owner;
-       PSID group;
+       PSID owner = 0;
+       PSID group = 0;
        if(!GetSecurityInfo(handle, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION, &owner, &group, 0, 0, &sec_desc))
        {
                CloseHandle(handle);
                throw system_error("GetSecurityInfo");
        }
 
-       result.owner = get_account_name(owner);
-       result.group = get_account_name(group);
+       if(owner)
+               result.owner = get_account_name(owner);
+       if(group)
+               result.group = get_account_name(group);
 
        LocalFree(sec_desc);
 
@@ -129,7 +135,12 @@ Stat Stat::stat(const Path &path)
        struct stat st;
        int ret = ::stat(path.str().c_str(), &st);
        if(ret==-1)
-               throw system_error("stat");
+       {
+               if(errno==ENOENT)
+                       return Stat();
+               else
+                       throw system_error("stat");
+       }
 
        return Private::from_struct_stat(st);
 #endif
@@ -143,7 +154,12 @@ Stat Stat::lstat(const Path &path)
        struct stat st;
        int ret = ::lstat(path.str().c_str(), &st);
        if(ret==-1)
-               throw system_error("lstat");
+       {
+               if(errno==ENOENT)
+                       return Stat();
+               else
+                       throw system_error("lstat");
+       }
 
        return Private::from_struct_stat(st);
 #endif