diff options
Diffstat (limited to 'compat/mingw.c')
-rw-r--r-- | compat/mingw.c | 94 |
1 files changed, 24 insertions, 70 deletions
diff --git a/compat/mingw.c b/compat/mingw.c index 45733f9e04..3dbe6a77ff 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1,4 +1,5 @@ #include "../git-compat-util.h" +#include "win32.h" #include "../strbuf.h" unsigned int _CRT_fmode = _O_BINARY; @@ -31,12 +32,6 @@ static inline time_t filetime_to_time_t(const FILETIME *ft) return (time_t)winTime; } -static inline size_t size_to_blocks(size_t s) -{ - return (s+511)/512; -} - -extern int _getdrive( void ); /* We keep the do_lstat code in a separate function to avoid recursion. * When a path ends with a slash, the stat will fail with ENOENT. In * this case, we strip the trailing slashes and stat again. @@ -45,46 +40,19 @@ static int do_lstat(const char *file_name, struct stat *buf) { WIN32_FILE_ATTRIBUTE_DATA fdata; - if (GetFileAttributesExA(file_name, GetFileExInfoStandard, &fdata)) { - int fMode = S_IREAD; - if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - fMode |= S_IFDIR; - else - fMode |= S_IFREG; - if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - fMode |= S_IWRITE; - + if (!(errno = get_file_attr(file_name, &fdata))) { buf->st_ino = 0; buf->st_gid = 0; buf->st_uid = 0; - buf->st_mode = fMode; + buf->st_nlink = 1; + buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */ - buf->st_blocks = size_to_blocks(buf->st_size); - buf->st_dev = _getdrive() - 1; + buf->st_dev = buf->st_rdev = 0; /* not used by Git */ buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime)); buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime)); buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime)); - errno = 0; return 0; } - - switch (GetLastError()) { - case ERROR_ACCESS_DENIED: - case ERROR_SHARING_VIOLATION: - case ERROR_LOCK_VIOLATION: - case ERROR_SHARING_BUFFER_EXCEEDED: - errno = EACCES; - break; - case ERROR_BUFFER_OVERFLOW: - errno = ENAMETOOLONG; - break; - case ERROR_NOT_ENOUGH_MEMORY: - errno = ENOMEM; - break; - default: - errno = ENOENT; - break; - } return -1; } @@ -94,7 +62,7 @@ static int do_lstat(const char *file_name, struct stat *buf) * complete. Note that Git stat()s are redirected to mingw_lstat() * too, since Windows doesn't really handle symlinks that well. */ -int mingw_lstat(const char *file_name, struct mingw_stat *buf) +int mingw_lstat(const char *file_name, struct stat *buf) { int namelen; static char alt_name[PATH_MAX]; @@ -122,8 +90,7 @@ int mingw_lstat(const char *file_name, struct mingw_stat *buf) } #undef fstat -#undef stat -int mingw_fstat(int fd, struct mingw_stat *buf) +int mingw_fstat(int fd, struct stat *buf) { HANDLE fh = (HANDLE)_get_osfhandle(fd); BY_HANDLE_FILE_INFORMATION fdata; @@ -133,39 +100,17 @@ int mingw_fstat(int fd, struct mingw_stat *buf) return -1; } /* direct non-file handles to MS's fstat() */ - if (GetFileType(fh) != FILE_TYPE_DISK) { - struct stat st; - if (fstat(fd, &st)) - return -1; - buf->st_ino = st.st_ino; - buf->st_gid = st.st_gid; - buf->st_uid = st.st_uid; - buf->st_mode = st.st_mode; - buf->st_size = st.st_size; - buf->st_blocks = size_to_blocks(buf->st_size); - buf->st_dev = st.st_dev; - buf->st_atime = st.st_atime; - buf->st_mtime = st.st_mtime; - buf->st_ctime = st.st_ctime; - return 0; - } + if (GetFileType(fh) != FILE_TYPE_DISK) + return fstat(fd, buf); if (GetFileInformationByHandle(fh, &fdata)) { - int fMode = S_IREAD; - if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - fMode |= S_IFDIR; - else - fMode |= S_IFREG; - if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - fMode |= S_IWRITE; - buf->st_ino = 0; buf->st_gid = 0; buf->st_uid = 0; - buf->st_mode = fMode; + buf->st_nlink = 1; + buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes); buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */ - buf->st_blocks = size_to_blocks(buf->st_size); - buf->st_dev = _getdrive() - 1; + buf->st_dev = buf->st_rdev = 0; /* not used by Git */ buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime)); buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime)); buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime)); @@ -283,8 +228,13 @@ int poll(struct pollfd *ufds, unsigned int nfds, int timeout) { int i, pending; - if (timeout != -1) + if (timeout >= 0) { + if (nfds == 0) { + Sleep(timeout); + return 0; + } return errno = EINVAL, error("poll timeout not supported"); + } /* When there is only one fd to wait for, then we pretend that * input is available and let the actual wait happen when the @@ -586,12 +536,16 @@ static pid_t mingw_spawnve(const char *cmd, const char **argv, char **env, * would normally create a console window. But * since we'll be redirecting std streams, we do * not need the console. + * It is necessary to use DETACHED_PROCESS + * instead of CREATE_NO_WINDOW to make ssh + * recognize that it has no console. */ - flags = CREATE_NO_WINDOW; + flags = DETACHED_PROCESS; } else { /* There is already a console. If we specified - * CREATE_NO_WINDOW here, too, Windows would + * DETACHED_PROCESS here, too, Windows would * disassociate the child from the console. + * The same is true for CREATE_NO_WINDOW. * Go figure! */ flags = 0; |