# HG changeset patch
# User Adrian Buehlmann <[email protected]>
# Date 1244728880 -7200
# Node ID 02421951ec021aa54cdc7d465d123e3cefe6a2a9
# Parent b325289450286a1814e3ab54adc585fa352c4e0c
shellext: allow other processes to rename files we have open
- introduce new function fopenReadRenameAllowed in TortoiseUtils.cpp
- use it to open .hg/dirstate and .hg/thgstatus
diff --git a/win32/shellext/DirectoryStatus.cpp
b/win32/shellext/DirectoryStatus.cpp
--- a/win32/shellext/DirectoryStatus.cpp
+++ b/win32/shellext/DirectoryStatus.cpp
@@ -18,6 +18,7 @@
#include "DirectoryStatus.h"
#include "Thgstatus.h"
+#include "TortoiseUtils.h"
char DirectoryStatus::status(const std::string& relpath_) const
@@ -61,7 +62,7 @@ int DirectoryStatus::read(const std::str
std::string p = hgroot + "\\.hg\\thgstatus";
- FILE *f = fopen(p.c_str(), "rb");
+ FILE *f = fopenReadRenameAllowed(p.c_str());
if (!f)
{
TDEBUG_TRACE("DirectoryStatus::read: can't open '" << p << "'");
diff --git a/win32/shellext/TortoiseUtils.cpp b/win32/shellext/TortoiseUtils.cpp
--- a/win32/shellext/TortoiseUtils.cpp
+++ b/win32/shellext/TortoiseUtils.cpp
@@ -4,6 +4,10 @@
#include "errno.h"
#include <assert.h>
+#include <io.h>
+#include "FCNTL.H"
+
+
int WideCharToLocal(LPTSTR pLocal, LPWSTR pWide, DWORD dwChars)
{
*pLocal = 0;
@@ -242,3 +246,36 @@ bool IsHgRepo(const std::string& path)
return !GetHgRepoRoot(path).empty();
}
+
+// open a file for reading, allowing renames and deletes by other
+// processes while we have it open
+FILE* fopenReadRenameAllowed(const char* path)
+{
+ HANDLE fh = ::CreateFileA(
+ path, GENERIC_READ,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0, OPEN_EXISTING, 0, 0
+ );
+
+ if (fh == INVALID_HANDLE_VALUE)
+ return 0;
+
+ // get C runtime file descriptor from file handle
+ int fd = ::_open_osfhandle ((intptr_t)fh, _O_RDONLY);
+ if (fd == -1)
+ {
+ TDEBUG_TRACE("fopenReadRenameAllowed: _open_osfhandle failed");
+ return 0;
+ }
+
+ // get C runtime FILE from file descriptor
+ FILE* f = ::_fdopen(fd, "r");
+ if (f == 0)
+ {
+ TDEBUG_TRACE("fopenReadRenameAllowed: _fdopen failed");
+ return 0;
+ }
+
+ return f;
+}
+
diff --git a/win32/shellext/TortoiseUtils.h b/win32/shellext/TortoiseUtils.h
--- a/win32/shellext/TortoiseUtils.h
+++ b/win32/shellext/TortoiseUtils.h
@@ -38,5 +38,6 @@ HICON GetTortoiseIcon(const std::string
std::string GetHgRepoRoot(const std::string& path);
bool IsHgRepo(const std::string& path);
int GetRegistryConfig(const std::string& name, std::string& res);
+FILE* fopenReadRenameAllowed(const char* path);
#endif
diff --git a/win32/shellext/dirstate.cpp b/win32/shellext/dirstate.cpp
--- a/win32/shellext/dirstate.cpp
+++ b/win32/shellext/dirstate.cpp
@@ -18,13 +18,14 @@
#include "stdafx.h"
#include "dirstate.h"
+#include "TortoiseUtils.h"
std::auto_ptr<Dirstate> Dirstate::read(const std::string& path, bool& unset)
{
unset = false;
- FILE *f = fopen(path.c_str(), "rb");
+ FILE *f = fopenReadRenameAllowed(path.c_str());
if (!f)
{
TDEBUG_TRACE("Dirstate::read: can't open " << path);
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Tortoisehg-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tortoisehg-develop