Skip to content

Commit cdcb4a0

Browse files
authored
Merge pull request #2217 from gmittert/FromUnderTheirFeet
[Windows] Ensure files open with FILE_SHARE_DELETE
2 parents 0c8dd8a + 096d7a2 commit cdcb4a0

File tree

1 file changed

+68
-3
lines changed

1 file changed

+68
-3
lines changed

CoreFoundation/Base.subproj/CFPlatform.c

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -885,9 +885,73 @@ CF_EXPORT int _NS_rename(const char *oldName, const char *newName) {
885885

886886
CF_EXPORT int _NS_open(const char *name, int oflag, int pmode) {
887887
wchar_t *wide = createWideFileSystemRepresentation(name, NULL);
888-
int fd;
889-
_wsopen_s(&fd, wide, oflag, _SH_DENYNO, _S_IREAD | _S_IWRITE);
888+
889+
DWORD dwDesiredAccess = 0;
890+
switch (oflag & (O_RDONLY | O_WRONLY | O_RDWR)) {
891+
case _O_RDONLY:
892+
dwDesiredAccess = GENERIC_READ;
893+
break;
894+
case _O_WRONLY:
895+
dwDesiredAccess = GENERIC_WRITE;
896+
break;
897+
case _O_RDWR:
898+
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
899+
break;
900+
}
901+
902+
DWORD dwCreationDisposition;
903+
switch (oflag & (O_CREAT | O_EXCL | O_TRUNC)) {
904+
case O_CREAT:
905+
dwCreationDisposition = OPEN_ALWAYS;
906+
break;
907+
case O_EXCL:
908+
dwCreationDisposition = CREATE_NEW;
909+
break;
910+
case O_TRUNC:
911+
dwCreationDisposition = TRUNCATE_EXISTING;
912+
break;
913+
default:
914+
dwCreationDisposition = OPEN_EXISTING;
915+
}
916+
917+
// Backup semantics are required to receive a handle to a directory
918+
DWORD dwFlagsAndAttributes = FILE_FLAG_BACKUP_SEMANTICS;
919+
if (pmode & _S_IREAD) {
920+
dwFlagsAndAttributes |= FILE_ATTRIBUTE_READONLY;
921+
}
922+
923+
HANDLE handle = CreateFileW(wide, dwDesiredAccess, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
924+
/* lpSecurityAttributes= */NULL, dwCreationDisposition, dwFlagsAndAttributes,
925+
/* hTemplatefile= */ NULL);
890926
free(wide);
927+
if (handle == INVALID_HANDLE_VALUE) {
928+
DWORD error = GetLastError();
929+
switch (error) {
930+
case ERROR_ACCESS_DENIED:
931+
case ERROR_SHARING_VIOLATION:
932+
errno = EACCES;
933+
break;
934+
case ERROR_FILE_EXISTS:
935+
case ERROR_ALREADY_EXISTS:
936+
errno = EEXIST;
937+
break;
938+
case ERROR_FILE_NOT_FOUND:
939+
case ERROR_PATH_NOT_FOUND:
940+
errno = ENOENT;
941+
break;
942+
default:
943+
errno = EIO;
944+
break;
945+
}
946+
return -1;
947+
}
948+
949+
// _open_osfhandle handles _O_APPEND and _O_RDONLY
950+
int fd = _open_osfhandle((intptr_t)handle, oflag);
951+
if (fd == -1) {
952+
CloseHandle(handle);
953+
return -1;
954+
}
891955
return fd;
892956
}
893957

@@ -1446,8 +1510,9 @@ CF_EXPORT char **_CFEnviron(void) {
14461510
CF_CROSS_PLATFORM_EXPORT int _CFOpenFileWithMode(const char *path, int opts, mode_t mode) {
14471511
return open(path, opts, mode);
14481512
}
1513+
14491514
int _CFOpenFile(const char *path, int opts) {
1450-
return open(path, opts);
1515+
return open(path, opts, 0);
14511516
}
14521517

14531518
CF_CROSS_PLATFORM_EXPORT void *_CFReallocf(void *ptr, size_t size) {

0 commit comments

Comments
 (0)