mirror of
https://github.com/git/git.git
synced 2024-11-24 02:17:02 +08:00
Merge branch 'js/mingw-o-append'
Among the three codepaths we use O_APPEND to open a file for appending, one used for writing GIT_TRACE output requires O_APPEND implementation that behaves sensibly when multiple processes are writing to the same file. POSIX emulation used in the Windows port has been updated to improve in this area. * js/mingw-o-append: mingw: enable atomic O_APPEND
This commit is contained in:
commit
d18d09bb81
@ -341,12 +341,44 @@ int mingw_mkdir(const char *path, int mode)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mingw_open_append(wchar_t const *wfilename, int oflags, ...)
|
||||
{
|
||||
HANDLE handle;
|
||||
int fd;
|
||||
DWORD create = (oflags & O_CREAT) ? OPEN_ALWAYS : OPEN_EXISTING;
|
||||
|
||||
/* only these flags are supported */
|
||||
if ((oflags & ~O_CREAT) != (O_WRONLY | O_APPEND))
|
||||
return errno = ENOSYS, -1;
|
||||
|
||||
/*
|
||||
* FILE_SHARE_WRITE is required to permit child processes
|
||||
* to append to the file.
|
||||
*/
|
||||
handle = CreateFileW(wfilename, FILE_APPEND_DATA,
|
||||
FILE_SHARE_WRITE | FILE_SHARE_READ,
|
||||
NULL, create, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return errno = err_win_to_posix(GetLastError()), -1;
|
||||
/*
|
||||
* No O_APPEND here, because the CRT uses it only to reset the
|
||||
* file pointer to EOF on write(); but that is not necessary
|
||||
* for a file created with FILE_APPEND_DATA.
|
||||
*/
|
||||
fd = _open_osfhandle((intptr_t)handle, O_BINARY);
|
||||
if (fd < 0)
|
||||
CloseHandle(handle);
|
||||
return fd;
|
||||
}
|
||||
|
||||
int mingw_open (const char *filename, int oflags, ...)
|
||||
{
|
||||
typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...);
|
||||
va_list args;
|
||||
unsigned mode;
|
||||
int fd;
|
||||
wchar_t wfilename[MAX_PATH];
|
||||
open_fn_t open_fn;
|
||||
|
||||
va_start(args, oflags);
|
||||
mode = va_arg(args, int);
|
||||
@ -355,9 +387,14 @@ int mingw_open (const char *filename, int oflags, ...)
|
||||
if (filename && !strcmp(filename, "/dev/null"))
|
||||
filename = "nul";
|
||||
|
||||
if (oflags & O_APPEND)
|
||||
open_fn = mingw_open_append;
|
||||
else
|
||||
open_fn = _wopen;
|
||||
|
||||
if (xutftowcs_path(wfilename, filename) < 0)
|
||||
return -1;
|
||||
fd = _wopen(wfilename, oflags, mode);
|
||||
fd = open_fn(wfilename, oflags, mode);
|
||||
|
||||
if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) {
|
||||
DWORD attrs = GetFileAttributesW(wfilename);
|
||||
@ -375,7 +412,7 @@ int mingw_open (const char *filename, int oflags, ...)
|
||||
* CREATE_ALWAYS flag of CreateFile()).
|
||||
*/
|
||||
if (fd < 0 && errno == EACCES)
|
||||
fd = _wopen(wfilename, oflags & ~O_CREAT, mode);
|
||||
fd = open_fn(wfilename, oflags & ~O_CREAT, mode);
|
||||
if (fd >= 0 && set_hidden_flag(wfilename, 1))
|
||||
warning("could not mark '%s' as hidden.", filename);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user