Skip to content

Commit d5e6ca1

Browse files
cswareethomson
authored andcommitted
Allow to configure default file share mode for opening files
This can prevent FILE_SHARED_VIOLATIONS when used in tools such as TortoiseGit TGitCache and FILE_SHARE_DELETE, because files can be opened w/o being locked any more. Signed-off-by: Sven Strickroth <email@cs-ware.de>
1 parent 92d5a63 commit d5e6ca1

File tree

5 files changed

+37
-11
lines changed

5 files changed

+37
-11
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ v0.25 + 1
99

1010
### API additions
1111

12+
* You can now set the default share mode on Windows for opening files using
13+
`GIT_OPT_SET_WINDOWS_SHAREMODE` option with `git_libgit2_opts()`.
14+
You can query the current share mode with `GIT_OPT_GET_WINDOWS_SHAREMODE`.
15+
1216
### API removals
1317

1418
### Breaking API changes

include/git2/common.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ typedef enum {
180180
GIT_OPT_GET_USER_AGENT,
181181
GIT_OPT_ENABLE_OFS_DELTA,
182182
GIT_OPT_ENABLE_SYNCHRONOUS_OBJECT_CREATION,
183+
GIT_OPT_GET_WINDOWS_SHAREMODE,
184+
GIT_OPT_SET_WINDOWS_SHAREMODE,
183185
} git_libgit2_opt_t;
184186

185187
/**
@@ -284,6 +286,17 @@ typedef enum {
284286
* > - `user_agent` is the value that will be delivered as the
285287
* > User-Agent header on HTTP requests.
286288
*
289+
* * opts(GIT_OPT_SET_WINDOWS_SHAREMODE, unsigned long value)
290+
*
291+
* > Set the share mode used when opening files on Windows.
292+
* > For more information, see the documentation for CreateFile.
293+
* > The default is: FILE_SHARE_READ | FILE_SHARE_WRITE. This is
294+
* > ignored and unused on non-Windows platforms.
295+
*
296+
* * opts(GIT_OPT_GET_WINDOWS_SHAREMODE, unsigned long *value)
297+
*
298+
* > Get the share mode used when opening files on Windows.
299+
*
287300
* * opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, int enabled)
288301
*
289302
* > Enable strict input validation when creating new objects

src/settings.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,18 @@ int git_libgit2_opts(int key, ...)
231231
git_object__synchronous_writing = (va_arg(ap, int) != 0);
232232
break;
233233

234+
case GIT_OPT_GET_WINDOWS_SHAREMODE:
235+
#ifdef GIT_WIN32
236+
*(va_arg(ap, unsigned long *)) = git_win32__createfile_sharemode;
237+
#endif
238+
break;
239+
240+
case GIT_OPT_SET_WINDOWS_SHAREMODE:
241+
#ifdef GIT_WIN32
242+
git_win32__createfile_sharemode = va_arg(ap, unsigned long);
243+
#endif
244+
break;
245+
234246
default:
235247
giterr_set(GITERR_INVALID, "invalid option key");
236248
error = -1;

src/win32/posix.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "utf-conv.h"
1515
#include "dir.h"
1616

17+
extern unsigned long git_win32__createfile_sharemode;
18+
1719
typedef SOCKET GIT_SOCKET;
1820

1921
#define p_lseek(f,n,w) _lseeki64(f, n, w)

src/win32/posix_w32.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,6 @@
2626
#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
2727
#endif
2828

29-
/* Options which we always provide to _wopen.
30-
*
31-
* _O_BINARY - Raw access; no translation of CR or LF characters
32-
* _O_NOINHERIT - Do not mark the created handle as inheritable by child processes.
33-
* The Windows default is 'not inheritable', but the CRT's default (following
34-
* POSIX convention) is 'inheritable'. We have no desire for our handles to be
35-
* inheritable on Windows, so specify the flag to get default behavior back. */
36-
#define STANDARD_OPEN_FLAGS (_O_BINARY | _O_NOINHERIT)
37-
3829
/* Allowable mode bits on Win32. Using mode bits that are not supported on
3930
* Win32 (eg S_IRWXU) is generally ignored, but Wine warns loudly about it
4031
* so we simply remove them.
@@ -44,6 +35,9 @@
4435
/* GetFinalPathNameByHandleW signature */
4536
typedef DWORD(WINAPI *PFGetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, DWORD);
4637

38+
unsigned long git_win32__createfile_sharemode =
39+
FILE_SHARE_READ | FILE_SHARE_WRITE;
40+
4741
GIT_INLINE(void) set_errno(void)
4842
{
4943
switch (GetLastError()) {
@@ -489,7 +483,7 @@ int p_open(const char *path, int flags, ...)
489483
break;
490484
}
491485

492-
sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
486+
sharing = (DWORD)git_win32__createfile_sharemode;
493487

494488
switch (flags & (O_CREAT | O_TRUNC | O_EXCL)) {
495489
case O_CREAT | O_EXCL:
@@ -510,7 +504,8 @@ int p_open(const char *path, int flags, ...)
510504
break;
511505
}
512506

513-
attributes = (mode & S_IWRITE) ? FILE_ATTRIBUTE_NORMAL : FILE_ATTRIBUTE_READONLY;
507+
attributes = ((flags & O_CREAT) && !(mode & S_IWRITE)) ?
508+
FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL;
514509
osf_flags = flags & (O_RDONLY | O_APPEND);
515510

516511
do_with_retries(

0 commit comments

Comments
 (0)