git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] add GIT_FAST_STAT mode for Cygwin

From
Johannes Sixt <johannes.sixt@telecom.at>
Date
Sep 23, 2008, 19:03 UTC
Message-ID
<200809232103.09133.johannes.sixt@telecom.at>
In-Reply-To
<20080923140144.GN21650@dpotapov.dyndns.org>
On Dienstag, 23. September 2008, Dmitry Potapov wrote:
Show 6 quoted lines
> +static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
> +{ 
> +	long long winTime = ((long long)ft->dwHighDateTime << 32) + ft->dwLowDateTime;
> +	winTime -= 116444736000000000LL; /* Windows to Unix  Epoch conversion */
> +	ts->tv_sec = (time_t)(winTime/10000000); /* 100-nanosecond interval to seconds */
> +	ts->tv_nsec = (long)(winTime - ts->tv_sec) * 100; /* nanoseconds */ +}
+	ts->tv_nsec = (long)(winTime - ts->tv_sec*10000000LL) * 100;
Show 6 quoted lines
> +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);

You should do this in the caller; it would make this function's semantics much clearer.

Show 66 quoted lines
> +
> +	if (GetFileAttributesExA(file_name, GetFileExInfoStandard, &fdata)) {
> +		int fMode = S_IREAD;
> +		/*
> +		 * 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);
> +
> +		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
> +			fMode |= S_IFDIR;
> +		else
> +			fMode |= S_IFREG;
> +		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
> +			fMode |= S_IWRITE;
> +
> +		/* st_dev, st_rdev are not used by Git */
> +		buf->st_dev = buf->st_rdev = 0;
> +		/* it is difficult to obtain the inode number on Windows,
> +		 * so let's set it to zero as MinGW Git does. */
> +		buf->st_ino = 0;
> +		buf->st_mode = fMode;
> +		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);
> +		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:
> +		/* 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;

You do duplicate a lot of code here. Any chances to factor out the common parts? Start with platform specific function filetime_to_stat_time() that is your filetime_to_timespec() on Cygwin, but filetime_to_time_t() (which needs modification) on MinGW.

-- Hannes
Previous: Shawn O. PearceNext: Dmitry Potapov
Message 19 of 25 in “add GIT_FAST_STAT mode for Cygwin”
  1. add GIT_FAST_STAT mode for CygwinDmitry Potapov, Sep 23, 2008
  2. Alex RiesenSep 23, 2008
  3. Dmitry PotapovSep 23, 2008
  4. Jakub NarebskiSep 23, 2008
  5. Alex RiesenSep 24, 2008
  6. Dmitry PotapovSep 24, 2008
  7. Alex RiesenSep 24, 2008
  8. Shawn O. PearceSep 24, 2008
  9. Alex RiesenSep 24, 2008
  10. Shawn O. PearceSep 24, 2008
  11. Alex RiesenSep 24, 2008
  12. Shawn O. PearceSep 23, 2008
  13. Dmitry PotapovSep 23, 2008
  14. Shawn O. PearceSep 23, 2008
  15. Dmitry PotapovSep 23, 2008
  16. Shawn O. PearceSep 23, 2008
  17. Dmitry PotapovSep 23, 2008
  18. Shawn O. PearceSep 23, 2008
  19. Johannes SixtSep 23, 2008
  20. Dmitry PotapovSep 23, 2008
  21. Johannes SixtSep 23, 2008
  22. Dmitry PotapovSep 23, 2008
  23. Add a "fast stat" mode for CygwinMarcus Griep, Sep 27, 2008
  24. Alex RiesenSep 27, 2008
  25. Dmitry PotapovSep 27, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.