diff options
author | Chris Wilson <chris+github@qwirx.com> | 2006-09-03 23:48:34 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2006-09-03 23:48:34 +0000 |
commit | a64a6f4c9c71dfe925bf5492c6e6aa828611fba0 (patch) | |
tree | d4d4effec08878ab1767a5a5b399f1375a2c85b0 /lib | |
parent | 33c64c6247b677f6233d4c529ee162f34d1535fc (diff) |
(refs #3)
Always fill in st_uid, st_gid and st_nlink
Return zero size for directories
Improved emulation of Unix file modes (helps when restoring Windows files
on Unix)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/win32/emu.cpp | 66 |
1 files changed, 40 insertions, 26 deletions
diff --git a/lib/win32/emu.cpp b/lib/win32/emu.cpp index 41361409..c0bdd609 100644 --- a/lib/win32/emu.cpp +++ b/lib/win32/emu.cpp @@ -617,41 +617,55 @@ int emu_fstat(HANDLE hdir, struct stat * st) st->st_atime = ConvertFileTimeToTime_t(&fi.ftLastAccessTime); st->st_mtime = ConvertFileTimeToTime_t(&fi.ftLastWriteTime); - // size of the file - LARGE_INTEGER st_size; - if (!GetFileSizeEx(hdir, &st_size)) + if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - ::syslog(LOG_WARNING, "Failed to get file size: error %d", - GetLastError()); - errno = EACCES; - return -1; + st->st_size = 0; } + else + { + // size of the file + LARGE_INTEGER st_size; + memset(&st_size, 0, sizeof(st_size)); + + if (!GetFileSizeEx(hdir, &st_size)) + { + ::syslog(LOG_WARNING, "Failed to get file size: " + "error %d", GetLastError()); + errno = EACCES; + return -1; + } - conv.HighPart = st_size.HighPart; - conv.LowPart = st_size.LowPart; - st->st_size = (_off_t)conv.QuadPart; + conv.HighPart = st_size.HighPart; + conv.LowPart = st_size.LowPart; + st->st_size = (_off_t)conv.QuadPart; + } - //the mode of the file - st->st_mode = 0; - //DWORD res = GetFileAttributes((LPCSTR)tmpStr.c_str()); + // at the mo + st->st_uid = 0; + st->st_gid = 0; + st->st_nlink = 1; - if (INVALID_FILE_ATTRIBUTES != fi.dwFileAttributes) + // the mode of the file + // mode zero will make it impossible to restore on Unix + // (no access to anybody, including the owner). + // we'll fake a sensible mode: + // all objects get user read (0400) + // if it's a directory it gets user execute (0100) + // if it's not read-only it gets user write (0200) + st->st_mode = S_IREAD; + + if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if (fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - st->st_mode |= S_IFDIR; - } - else - { - st->st_mode |= S_IFREG; - } + st->st_mode |= S_IFDIR | S_IEXEC; } else { - ::syslog(LOG_WARNING, "Failed to get file attributes: " - "error %d", GetLastError()); - errno = EACCES; - return -1; + st->st_mode |= S_IFREG; + } + + if (!(fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + { + st->st_mode |= S_IWRITE; } return 0; |