cygwin: Remove the Win32 l/stat() implementation

Commit adbc0b6b ("cygwin: Use native Win32 API for stat", 30-09-2008) added a Win32 specific implementation of the stat functions. In order to handle absolute paths, cygwin mount points and symbolic links, this implementation may fall back on the standard cygwin l/stat() functions. Also, the choice of cygwin or Win32 functions is made lazily (by the first call(s) to l/stat) based on the state of some config variables. Unfortunately, this "schizophrenic stat" implementation has been the source of many problems ever since. For example, see commits 7faee6b8, 79748439, 452993c2, 085479e7, b8a97333, 924aaf3e, 05bab3ea and 0117c2f0. In order to avoid further problems, such as the issue raised by the new reference handling API, remove the Win32 l/stat() implementation. Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ramsay Jones committed Jun 22, 2013 at 20:42 UTC f66450ae94f28a565226c3e443df5433722c5672
9 files changed +2 -200
Documentation/config.txt
-11
@@ -213,17 +213,6 @@ The default is true, except linkgit:git-clone[1] or linkgit:git-init[1]
213 will probe and set core.fileMode false if appropriate when the
214 repository is created.
215
216 -core.ignoreCygwinFSTricks::
217 - This option is only used by Cygwin implementation of Git. If false,
218 - the Cygwin stat() and lstat() functions are used. This may be useful
219 - if your repository consists of a few separate directories joined in
220 - one hierarchy using Cygwin mount. If true, Git uses native Win32 API
221 - whenever it is possible and falls back to Cygwin functions only to
222 - handle symbol links. The native mode is more than twice faster than
223 - normal Cygwin l/stat() functions. True by default, unless core.filemode
224 - is true, in which case ignoreCygwinFSTricks is ignored as Cygwin's
225 - POSIX emulation is required to support core.filemode.
226 -
216 core.ignorecase::
217 If true, this option enables various workarounds to enable
218 Git to work better on filesystems that are not case sensitive,
Makefile
-1
@@ -654,7 +654,6 @@ LIB_H += color.h
654 LIB_H += column.h
655 LIB_H += commit.h
656 LIB_H += compat/bswap.h
657 -LIB_H += compat/cygwin.h
657 LIB_H += compat/mingw.h
658 LIB_H += compat/obstack.h
659 LIB_H += compat/poll/poll.h
compat/cygwin.c deleted
-157
@@ -1,157 +0,0 @@
1 -#define CYGWIN_C
2 -#define WIN32_LEAN_AND_MEAN
3 -#include <sys/stat.h>
4 -#include <sys/errno.h>
5 -#include "win32.h"
6 -#include "../git-compat-util.h"
7 -#include "../cache.h" /* to read configuration */
8 -
9 -/*
10 - * Return POSIX permission bits, regardless of core.ignorecygwinfstricks
11 - */
12 -int cygwin_get_st_mode_bits(const char *path, int *mode)
13 -{
14 - struct stat st;
15 - if (lstat(path, &st) < 0)
16 - return -1;
17 - *mode = st.st_mode;
18 - return 0;
19 -}
20 -
21 -static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
22 -{
23 - long long winTime = ((long long)ft->dwHighDateTime << 32) +
24 - ft->dwLowDateTime;
25 - winTime -= 116444736000000000LL; /* Windows to Unix Epoch conversion */
26 - /* convert 100-nsecond interval to seconds and nanoseconds */
27 - ts->tv_sec = (time_t)(winTime/10000000);
28 - ts->tv_nsec = (long)(winTime - ts->tv_sec*10000000LL) * 100;
29 -}
30 -
31 -#define size_to_blocks(s) (((s)+511)/512)
32 -
33 -/* do_stat is a common implementation for cygwin_lstat and cygwin_stat.
34 - *
35 - * To simplify its logic, in the case of cygwin symlinks, this implementation
36 - * falls back to the cygwin version of stat/lstat, which is provided as the
37 - * last argument.
38 - */
39 -static int do_stat(const char *file_name, struct stat *buf, stat_fn_t cygstat)
40 -{
41 - WIN32_FILE_ATTRIBUTE_DATA fdata;
42 -
43 - if (file_name[0] == '/')
44 - return cygstat (file_name, buf);
45 -
46 - if (!(errno = get_file_attr(file_name, &fdata))) {
47 - /*
48 - * If the system attribute is set and it is not a directory then
49 - * it could be a symbol link created in the nowinsymlinks mode.
50 - * Normally, Cygwin works in the winsymlinks mode, so this situation
51 - * is very unlikely. For the sake of simplicity of our code, let's
52 - * Cygwin to handle it.
53 - */
54 - if ((fdata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) &&
55 - !(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
56 - return cygstat(file_name, buf);
57 -
58 - /* fill out the stat structure */
59 - buf->st_dev = buf->st_rdev = 0; /* not used by Git */
60 - buf->st_ino = 0;
61 - buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
62 - buf->st_nlink = 1;
63 - buf->st_uid = buf->st_gid = 0;
64 -#ifdef __CYGWIN_USE_BIG_TYPES__
65 - buf->st_size = ((_off64_t)fdata.nFileSizeHigh << 32) +
66 - fdata.nFileSizeLow;
67 -#else
68 - buf->st_size = (off_t)fdata.nFileSizeLow;
69 -#endif
70 - buf->st_blocks = size_to_blocks(buf->st_size);
71 - filetime_to_timespec(&fdata.ftLastAccessTime, &buf->st_atim);
72 - filetime_to_timespec(&fdata.ftLastWriteTime, &buf->st_mtim);
73 - filetime_to_timespec(&fdata.ftCreationTime, &buf->st_ctim);
74 - return 0;
75 - } else if (errno == ENOENT) {
76 - /*
77 - * In the winsymlinks mode (which is the default), Cygwin
78 - * emulates symbol links using Windows shortcut files. These
79 - * files are formed by adding .lnk extension. So, if we have
80 - * not found the specified file name, it could be that it is
81 - * a symbol link. Let's Cygwin to deal with that.
82 - */
83 - return cygstat(file_name, buf);
84 - }
85 - return -1;
86 -}
87 -
88 -/* We provide our own lstat/stat functions, since the provided Cygwin versions
89 - * of these functions are too slow. These stat functions are tailored for Git's
90 - * usage, and therefore they are not meant to be complete and correct emulation
91 - * of lstat/stat functionality.
92 - */
93 -static int cygwin_lstat(const char *path, struct stat *buf)
94 -{
95 - return do_stat(path, buf, lstat);
96 -}
97 -
98 -static int cygwin_stat(const char *path, struct stat *buf)
99 -{
100 - return do_stat(path, buf, stat);
101 -}
102 -
103 -
104 -/*
105 - * At start up, we are trying to determine whether Win32 API or cygwin stat
106 - * functions should be used. The choice is determined by core.ignorecygwinfstricks.
107 - * Reading this option is not always possible immediately as git_dir may
108 - * not be set yet. So until it is set, use cygwin lstat/stat functions.
109 - * However, if core.filemode is set, we must use the Cygwin posix
110 - * stat/lstat as the Windows stat functions do not determine posix filemode.
111 - *
112 - * Note that git_cygwin_config() does NOT call git_default_config() and this
113 - * is deliberate. Many commands read from config to establish initial
114 - * values in variables and later tweak them from elsewhere (e.g. command line).
115 - * init_stat() is called lazily on demand, typically much late in the program,
116 - * and calling git_default_config() from here would break such variables.
117 - */
118 -static int native_stat = 1;
119 -static int core_filemode = 1; /* matches trust_executable_bit default */
120 -
121 -static int git_cygwin_config(const char *var, const char *value, void *cb)
122 -{
123 - if (!strcmp(var, "core.ignorecygwinfstricks"))
124 - native_stat = git_config_bool(var, value);
125 - else if (!strcmp(var, "core.filemode"))
126 - core_filemode = git_config_bool(var, value);
127 - return 0;
128 -}
129 -
130 -static int init_stat(void)
131 -{
132 - if (have_git_dir() && git_config(git_cygwin_config,NULL)) {
133 - if (!core_filemode && native_stat) {
134 - cygwin_stat_fn = cygwin_stat;
135 - cygwin_lstat_fn = cygwin_lstat;
136 - } else {
137 - cygwin_stat_fn = stat;
138 - cygwin_lstat_fn = lstat;
139 - }
140 - return 0;
141 - }
142 - return 1;
143 -}
144 -
145 -static int cygwin_stat_stub(const char *file_name, struct stat *buf)
146 -{
147 - return (init_stat() ? stat : *cygwin_stat_fn)(file_name, buf);
148 -}
149 -
150 -static int cygwin_lstat_stub(const char *file_name, struct stat *buf)
151 -{
152 - return (init_stat() ? lstat : *cygwin_lstat_fn)(file_name, buf);
153 -}
154 -
155 -stat_fn_t cygwin_stat_fn = cygwin_stat_stub;
156 -stat_fn_t cygwin_lstat_fn = cygwin_lstat_stub;
157 -
compat/cygwin.h deleted
-14
@@ -1,14 +0,0 @@
1 -#include <sys/types.h>
2 -#include <sys/stat.h>
3 -
4 -typedef int (*stat_fn_t)(const char*, struct stat*);
5 -extern stat_fn_t cygwin_stat_fn;
6 -extern stat_fn_t cygwin_lstat_fn;
7 -int cygwin_get_st_mode_bits(const char *path, int *mode);
8 -
9 -#define get_st_mode_bits(p,m) cygwin_get_st_mode_bits((p),(m))
10 -#ifndef CYGWIN_C
11 -/* cygwin.c needs the original lstat() */
12 -#define stat(path, buf) (*cygwin_stat_fn)(path, buf)
13 -#define lstat(path, buf) (*cygwin_lstat_fn)(path, buf)
14 -#endif
config.mak.uname
-1
@@ -170,7 +170,6 @@ ifeq ($(uname_O),Cygwin)
170 # Try commenting this out if you suspect MMAP is more efficient
171 NO_MMAP = YesPlease
172 X = .exe
173 - COMPAT_OBJS += compat/cygwin.o
173 UNRELIABLE_FSTAT = UnfortunatelyYes
174 SPARSE_FLAGS = -isystem /usr/include/w32api -Wno-one-bit-signed-bitfield
175 endif
contrib/completion/git-completion.bash
-1
@@ -1957,7 +1957,6 @@ _git_config ()
1957 core.fileMode
1958 core.fsyncobjectfiles
1959 core.gitProxy
1960 - core.ignoreCygwinFSTricks
1960 core.ignoreStat
1961 core.ignorecase
1962 core.logAllRefUpdates
git-compat-util.h
-3
@@ -129,8 +129,6 @@
129 #include <poll.h>
130 #endif
131
132 -extern int get_st_mode_bits(const char *path, int *mode);
133 -
132 #if defined(__MINGW32__)
133 /* pull in Windows compatibility stuff */
134 #include "compat/mingw.h"
@@ -171,7 +169,6 @@ typedef unsigned long uintptr_t;
169 #undef _XOPEN_SOURCE
170 #include <grp.h>
171 #define _XOPEN_SOURCE 600
174 -#include "compat/cygwin.h"
172 #else
173 #undef _ALL_SOURCE /* AIX 5.3L defines a struct list with _ALL_SOURCE. */
174 #include <grp.h>
help.c
+1 -4
@@ -107,10 +107,7 @@ static int is_executable(const char *name)
107 !S_ISREG(st.st_mode))
108 return 0;
109
110 -#if defined(GIT_WINDOWS_NATIVE) || defined(__CYGWIN__)
111 -#if defined(__CYGWIN__)
112 -if ((st.st_mode & S_IXUSR) == 0)
113 -#endif
110 +#if defined(GIT_WINDOWS_NATIVE)
111 { /* cannot trust the executable bit, peek into the file instead */
112 char buf[3] = { 0 };
113 int n;
path.c
+1 -8
@@ -5,13 +5,7 @@
5 #include "strbuf.h"
6 #include "string-list.h"
7
8 -#ifndef get_st_mode_bits
9 -/*
10 - * The replacement lstat(2) we use on Cygwin is incomplete and
11 - * may return wrong permission bits. Most of the time we do not care,
12 - * but the callsites of this wrapper do care.
13 - */
14 -int get_st_mode_bits(const char *path, int *mode)
8 +static int get_st_mode_bits(const char *path, int *mode)
9 {
10 struct stat st;
11 if (lstat(path, &st) < 0)
@@ -19,7 +13,6 @@ int get_st_mode_bits(const char *path, int *mode)
13 *mode = st.st_mode;
14 return 0;
15 }
22 -#endif
16
17 static char bad_path[] = "/bad-path/";
18