From: Alex Riesen Date: Sun, 28 Sep 2008 09:50:45 GMT Subject: Re: [PATCH 4/4] cygwin: Use native Win32 API for stat Message-ID: <20080928095045.GA3746@blimp.localhost> In-Reply-To: <20080927084349.GC21650@dpotapov.dyndns.org> Dmitry Potapov, Sat, Sep 27, 2008 10:43:49 +0200: > Despite all efforts to make the fast implementation as robust as possible, > it may not work well for some very rare situations. I am aware only one > situation: use Cygwin mount to bind unrelated paths inside repository > together. Therefore, the core.cygwinnativestat configuration option is > provided, which controls whether native or Cygwin version of stat is used. cygwin.tryWindowsState? (I think cygwin has to get its own section) > +static int do_stat(const char *file_name, struct stat *buf, stat_fn_t cygstat) > +{ > + WIN32_FILE_ATTRIBUTE_DATA fdata; > + > + if (file_name[0] == '/') > + return cygstat (file_name, buf); > + > + if (!(errno = get_file_attr(file_name, &fdata))) { > + /* > + * If the system attribute is set and it is not a directory then > + * it could be a symbol link created in the nowinsymlinks mode. > + * Normally, Cygwin works in the winsymlinks mode, so this situation > + * is very unlikely. For the sake of simplicity of our code, let's > + * Cygwin to handle it. > + */ > + if ((fdata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) && > + !(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) > + return cygstat (file_name, buf); formatting: space after function name. > + > + /* fill out the stat structure */ > + buf->st_dev = buf->st_rdev = 0; /* not used by Git */ > + buf->st_ino = 0; > + buf->st_mode = file_attr_to_st_mode (fdata.dwFileAttributes); > + buf->st_nlink = 1; > + buf->st_uid = buf->st_gid = 0; > +#ifdef __CYGWIN_USE_BIG_TYPES__ > + buf->st_size = ((_off64_t)fdata.nFileSizeHigh << 32) + > + fdata.nFileSizeLow; > +#else > + buf->st_size = (off_t)fdata.nFileSizeLow; > +#endif > + buf->st_blocks = size_to_blocks(buf->st_size); > + filetime_to_timespec(&fdata.ftLastAccessTime, &buf->st_atim); > + filetime_to_timespec(&fdata.ftLastWriteTime, &buf->st_mtim); > + filetime_to_timespec(&fdata.ftCreationTime, &buf->st_ctim); > + return 0; > + } else if (errno == ENOENT) { > + /* > + * In the winsymlinks mode (which is the default), Cygwin > + * emulates symbol links using Windows shortcut files. These > + * files are formed by adding .lnk extension. So, if we have > + * not found the specified file name, it could be that it is > + * a symbol link. Let's Cygwin to deal with that. > + */ > + return cygstat (file_name, buf); > + } > + return -1; > +} I like it and will be keeping in my tree. Thanks!