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
next prev 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