public inbox for git@vger.kernel.org 
 help / color / mirror / Atom feed
From: Johannes Sixt <johannes.sixt@telecom•at>
To: Dmitry Potapov <dpotapov@gmail•com>
Cc: git@vger•kernel.org, Junio C Hamano <gitster@pobox•com>,
	Steffen Prohaska <prohaska@zib•de>
Subject: Re: [PATCH] add GIT_FAST_STAT mode for Cygwin
Date: Tue, 23 Sep 2008 21:03:08 +0200	[thread overview]
Message-ID: <200809232103.09133.johannes.sixt@telecom.at> (raw)
In-Reply-To: <20080923140144.GN21650@dpotapov.dyndns.org>

On Dienstag, 23. September 2008, Dmitry Potapov wrote:
> +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;

> +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.

> +
> +	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

  parent reply	other threads:[~2008-09-23 19:04 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-23 14:06 [PATCH] add GIT_FAST_STAT mode for Cygwin Dmitry Potapov
2008-09-23 14:37 ` Alex Riesen
2008-09-23 16:52   ` Dmitry Potapov
2008-09-23 17:51     ` Jakub Narebski
2008-09-24 11:25     ` Alex Riesen
2008-09-24 14:03       ` Dmitry Potapov
2008-09-24 14:42         ` Alex Riesen
2008-09-24 15:02           ` Shawn O. Pearce
2008-09-24 15:09             ` Alex Riesen
2008-09-24 15:16               ` Shawn O. Pearce
2008-09-24 15:32                 ` Alex Riesen
2008-09-23 15:31 ` Shawn O. Pearce
2008-09-23 17:12   ` Dmitry Potapov
2008-09-23 19:06     ` Shawn O. Pearce
2008-09-23 20:04       ` Dmitry Potapov
2008-09-23 20:17         ` Shawn O. Pearce
2008-09-23 21:28           ` Dmitry Potapov
2008-09-23 21:58             ` Shawn O. Pearce
2008-09-23 19:03 ` Johannes Sixt [this message]
2008-09-23 19:48   ` Dmitry Potapov
2008-09-23 20:41     ` Johannes Sixt
2008-09-23 21:11       ` Dmitry Potapov
2008-09-27  7:02 ` [PATCH v2] Add a "fast stat" " Marcus Griep
2008-09-27  8:35   ` Alex Riesen
2008-09-27 10:39   ` Dmitry Potapov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200809232103.09133.johannes.sixt@telecom.at \
    --to=johannes.sixt@telecom$(echo .)at \
    --cc=dpotapov@gmail$(echo .)com \
    --cc=git@vger$(echo .)kernel.org \
    --cc=gitster@pobox$(echo .)com \
    --cc=prohaska@zib$(echo .)de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox