From: Johannes Sixt <j.sixt@viscovery.net>
To: Nicolas Pitre <nico@cam.org>
Cc: Alex Riesen <raa.lkml@gmail.com>,
Junio C Hamano <gitster@pobox.com>,
Git Mailing List <git@vger.kernel.org>
Subject: [PATCH] compat/mingw.c: Teach mingw_rename() to replace read-only files
Date: Wed, 19 Nov 2008 17:25:27 +0100 [thread overview]
Message-ID: <49243DF7.7000604@viscovery.net> (raw)
In-Reply-To: <49242821.50604@viscovery.net>
From: Johannes Sixt <j6t@kdbg.org>
On POSIX, rename() can replace files that are not writable. On Windows,
however, read-only files cannot be replaced without additional efforts:
We have to make the destination writable first.
Since the situations where the destination is read-only are rare, we do not
make the destination writable on every invocation, but only if the first
try to rename a file failed with an "access denied" error.
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
Johannes Sixt schrieb:
> Nicolas Pitre schrieb:
>> On Wed, 19 Nov 2008, Johannes Sixt wrote:
>>> The unusual case is where you do this:
>>>
>>> $ git rev-list -10 HEAD | git pack-objects foobar
>>>
>>> twice in a row: In this case the second invocation fails on Windows
>>> because the destination pack file already exists *and* is open. But not
>>> even git-repack does this even if it is called twice. OTOH, the test case
>>> *does* exactly this.
>> OK.... Well, despite my earlier assertion, I think the above should be a
>> valid operation.
Would you please clarify which operation you exactly mean? As is written
above, or with .git/objects/pack/foobar instead like in the test case?
>> I'm looking at it now. I'm therefore revoking my earlier ACK as well
>> (better keep that test case alive).
>
> Hold on a moment: When I tested the above sequence, I was fooled by a flaw
> in mingw_rename() (it doesn't replace read-only files). With that fixed...
Here is this fix.
-- Hannes
compat/mingw.c | 15 ++++++++++++---
1 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/compat/mingw.c b/compat/mingw.c
index b534a8a..3dbe6a7 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -819,6 +819,8 @@ int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz)
#undef rename
int mingw_rename(const char *pold, const char *pnew)
{
+ DWORD attrs;
+
/*
* Try native rename() first to get errno right.
* It is based on MoveFile(), which cannot overwrite existing files.
@@ -830,12 +832,19 @@ int mingw_rename(const char *pold, const char *pnew)
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
return 0;
/* TODO: translate more errors */
- if (GetLastError() == ERROR_ACCESS_DENIED) {
- DWORD attrs = GetFileAttributes(pnew);
- if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
+ if (GetLastError() == ERROR_ACCESS_DENIED &&
+ (attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) {
+ if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
errno = EISDIR;
return -1;
}
+ if ((attrs & FILE_ATTRIBUTE_READONLY) &&
+ SetFileAttributes(pnew, attrs & ~FILE_ATTRIBUTE_READONLY)) {
+ if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
+ return 0;
+ /* revert file attributes on failure */
+ SetFileAttributes(pnew, attrs);
+ }
}
errno = EACCES;
return -1;
--
1.6.0.4.1694.g07ac
next prev parent reply other threads:[~2008-11-19 16:26 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-19 11:13 [PATCH] Fix handle leak in builtin-pack-objects Alex Riesen
2008-11-19 11:54 ` Johannes Sixt
2008-11-19 12:13 ` Alex Riesen
2008-11-19 12:26 ` Johannes Sixt
2008-11-19 12:55 ` Nicolas Pitre
2008-11-19 13:06 ` Johannes Sixt
2008-11-19 14:31 ` Nicolas Pitre
2008-11-19 13:34 ` Alex Riesen
2008-11-19 13:55 ` Johannes Sixt
2008-11-19 14:17 ` Alex Riesen
2008-11-19 14:42 ` Nicolas Pitre
2008-11-19 14:52 ` Johannes Sixt
2008-11-19 16:25 ` Johannes Sixt [this message]
2008-11-26 13:18 ` Alex Riesen
2008-11-26 14:33 ` Nicolas Pitre
2008-11-26 18:43 ` Alex Riesen
2008-12-09 19:26 ` [PATCH] make sure packs to be replaced are closed beforehand Nicolas Pitre
2008-12-09 19:33 ` Alex Riesen
2008-12-10 7:37 ` Johannes Sixt
2008-12-10 8:27 ` Junio C Hamano
2008-12-10 9:36 ` Alex Riesen
2008-11-19 12:45 ` [PATCH] Fix handle leak in builtin-pack-objects Nicolas Pitre
2008-11-19 13:30 ` Alex Riesen
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=49243DF7.7000604@viscovery.net \
--to=j.sixt@viscovery.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=nico@cam.org \
--cc=raa.lkml@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.