summaryrefslogtreecommitdiff
path: root/src/win32
diff options
context:
space:
mode:
Diffstat (limited to 'src/win32')
-rw-r--r--src/win32/posix.h10
-rw-r--r--src/win32/posix_w32.c20
-rw-r--r--src/win32/w32_util.h55
-rw-r--r--src/win32/win32-compat.h7
4 files changed, 75 insertions, 17 deletions
diff --git a/src/win32/posix.h b/src/win32/posix.h
index ac98fd864..5fab267c2 100644
--- a/src/win32/posix.h
+++ b/src/win32/posix.h
@@ -9,6 +9,7 @@
#include "common.h"
#include "../posix.h"
+#include "win32-compat.h"
#include "path_w32.h"
#include "utf-conv.h"
#include "dir.h"
@@ -16,12 +17,13 @@
typedef SOCKET GIT_SOCKET;
#define p_lseek(f,n,w) _lseeki64(f, n, w)
-#define p_fstat(f,b) _fstat64(f, b)
+
+extern int p_fstat(int fd, struct stat *buf);
extern int p_lstat(const char *file_name, struct stat *buf);
-extern int p_stat(const char* path, struct stat* buf);
+extern int p_stat(const char* path, struct stat *buf);
-extern int p_utimes(const char *filename, const struct timeval times[2]);
-extern int p_futimes(int fd, const struct timeval times[2]);
+extern int p_utimes(const char *filename, const struct p_timeval times[2]);
+extern int p_futimes(int fd, const struct p_timeval times[2]);
extern int p_readlink(const char *path, char *buf, size_t bufsiz);
extern int p_symlink(const char *old, const char *new);
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 414cb4701..fea634b00 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -210,7 +210,7 @@ int p_lstat_posixly(const char *filename, struct stat *buf)
return do_lstat(filename, buf, true);
}
-int p_utimes(const char *filename, const struct timeval times[2])
+int p_utimes(const char *filename, const struct p_timeval times[2])
{
int fd, error;
@@ -223,7 +223,7 @@ int p_utimes(const char *filename, const struct timeval times[2])
return error;
}
-int p_futimes(int fd, const struct timeval times[2])
+int p_futimes(int fd, const struct p_timeval times[2])
{
HANDLE handle;
FILETIME atime = {0}, mtime = {0};
@@ -398,6 +398,22 @@ static int follow_and_lstat_link(git_win32_path path, struct stat* buf)
return lstat_w(target_w, buf, false);
}
+int p_fstat(int fd, struct stat *buf)
+{
+ BY_HANDLE_FILE_INFORMATION fhInfo;
+
+ HANDLE fh = (HANDLE)_get_osfhandle(fd);
+
+ if (fh == INVALID_HANDLE_VALUE ||
+ !GetFileInformationByHandle(fh, &fhInfo)) {
+ errno = EBADF;
+ return -1;
+ }
+
+ git_win32__file_information_to_stat(buf, &fhInfo);
+ return 0;
+}
+
int p_stat(const char* path, struct stat* buf)
{
git_win32_path path_w;
diff --git a/src/win32/w32_util.h b/src/win32/w32_util.h
index 727ed1cef..2e475e5e9 100644
--- a/src/win32/w32_util.h
+++ b/src/win32/w32_util.h
@@ -96,7 +96,7 @@ GIT_INLINE(void) git_win32__filetime_to_timespec(
}
GIT_INLINE(void) git_win32__timeval_to_filetime(
- FILETIME *ft, const struct timeval tv)
+ FILETIME *ft, const struct p_timeval tv)
{
long long ticks = (tv.tv_sec * 10000000LL) +
(tv.tv_usec * 10LL) + 116444736000000000LL;
@@ -105,19 +105,25 @@ GIT_INLINE(void) git_win32__timeval_to_filetime(
ft->dwLowDateTime = (ticks & 0xffffffffLL);
}
-GIT_INLINE(int) git_win32__file_attribute_to_stat(
+GIT_INLINE(void) git_win32__stat_init(
struct stat *st,
- const WIN32_FILE_ATTRIBUTE_DATA *attrdata,
- const wchar_t *path)
+ DWORD dwFileAttributes,
+ DWORD nFileSizeHigh,
+ DWORD nFileSizeLow,
+ FILETIME ftCreationTime,
+ FILETIME ftLastAccessTime,
+ FILETIME ftLastWriteTime)
{
mode_t mode = S_IREAD;
- if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ memset(st, 0, sizeof(struct stat));
+
+ if (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
mode |= S_IFDIR;
else
mode |= S_IFREG;
- if ((attrdata->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+ if ((dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
mode |= S_IWRITE;
st->st_ino = 0;
@@ -125,12 +131,39 @@ GIT_INLINE(int) git_win32__file_attribute_to_stat(
st->st_uid = 0;
st->st_nlink = 1;
st->st_mode = mode;
- st->st_size = ((git_off_t)attrdata->nFileSizeHigh << 32) + attrdata->nFileSizeLow;
+ st->st_size = ((git_off_t)nFileSizeHigh << 32) + nFileSizeLow;
st->st_dev = _getdrive() - 1;
st->st_rdev = st->st_dev;
- git_win32__filetime_to_timespec(&(attrdata->ftLastAccessTime), &(st->st_atim));
- git_win32__filetime_to_timespec(&(attrdata->ftLastWriteTime), &(st->st_mtim));
- git_win32__filetime_to_timespec(&(attrdata->ftCreationTime), &(st->st_ctim));
+ git_win32__filetime_to_timespec(&ftLastAccessTime, &(st->st_atim));
+ git_win32__filetime_to_timespec(&ftLastWriteTime, &(st->st_mtim));
+ git_win32__filetime_to_timespec(&ftCreationTime, &(st->st_ctim));
+}
+
+GIT_INLINE(void) git_win32__file_information_to_stat(
+ struct stat *st,
+ const BY_HANDLE_FILE_INFORMATION *fileinfo)
+{
+ git_win32__stat_init(st,
+ fileinfo->dwFileAttributes,
+ fileinfo->nFileSizeHigh,
+ fileinfo->nFileSizeLow,
+ fileinfo->ftCreationTime,
+ fileinfo->ftLastAccessTime,
+ fileinfo->ftLastWriteTime);
+}
+
+GIT_INLINE(int) git_win32__file_attribute_to_stat(
+ struct stat *st,
+ const WIN32_FILE_ATTRIBUTE_DATA *attrdata,
+ const wchar_t *path)
+{
+ git_win32__stat_init(st,
+ attrdata->dwFileAttributes,
+ attrdata->nFileSizeHigh,
+ attrdata->nFileSizeLow,
+ attrdata->ftCreationTime,
+ attrdata->ftLastAccessTime,
+ attrdata->ftLastWriteTime);
if (attrdata->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && path) {
git_win32_path target;
@@ -139,7 +172,7 @@ GIT_INLINE(int) git_win32__file_attribute_to_stat(
st->st_mode = (st->st_mode & ~S_IFMT) | S_IFLNK;
/* st_size gets the UTF-8 length of the target name, in bytes,
- * not counting the NULL terminator */
+ * not counting the NULL terminator */
if ((st->st_size = git__utf16_to_8(NULL, 0, target)) < 0) {
giterr_set(GITERR_OS, "Could not convert reparse point name for '%s'", path);
return -1;
diff --git a/src/win32/win32-compat.h b/src/win32/win32-compat.h
index d3a5b68a3..dff1f45be 100644
--- a/src/win32/win32-compat.h
+++ b/src/win32/win32-compat.h
@@ -13,6 +13,13 @@
#include <sys/stat.h>
#include <sys/types.h>
+typedef long suseconds_t;
+
+struct p_timeval {
+ time_t tv_sec;
+ suseconds_t tv_usec;
+};
+
struct p_timespec {
time_t tv_sec;
long tv_nsec;