diff options
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r-- | winsup/cygwin/syscalls.cc | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 8a995e8..b776174 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -670,8 +670,8 @@ check_dir_not_empty (HANDLE dir, path_conv &pc) return STATUS_SUCCESS; } -NTSTATUS -unlink_nt (path_conv &pc) +static NTSTATUS +_unlink_nt (path_conv &pc, bool shareable) { NTSTATUS status; HANDLE fh, fh_ro = NULL; @@ -793,6 +793,9 @@ retry_open: bin so that it actually disappears from its directory even though its in use. Otherwise, if opening doesn't fail, the file is not in use and we can go straight to setting the delete disposition flag. + However, while we have the file open with FILE_SHARE_DELETE, using + this file via another hardlink for anything other than DELETE by + concurrent processes fails. The 'shareable' argument is to prevent this. NOTE: The missing sharing modes FILE_SHARE_READ and FILE_SHARE_WRITE do NOT result in a STATUS_SHARING_VIOLATION, if another handle is @@ -802,7 +805,10 @@ retry_open: will succeed. So, apparently there is no reliable way to find out if a file is already open elsewhere for other purposes than reading and writing data. */ - status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_DELETE, flags); + if (shareable) + status = STATUS_SHARING_VIOLATION; + else + status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_DELETE, flags); /* STATUS_SHARING_VIOLATION is what we expect. STATUS_LOCK_NOT_GRANTED can be generated under not quite clear circumstances when trying to open a file on NFS with FILE_SHARE_DELETE only. This has been observed with @@ -1052,6 +1058,18 @@ out: return status; } +NTSTATUS +unlink_nt (path_conv &pc) +{ + return _unlink_nt (pc, false); +} + +NTSTATUS +unlink_nt_shareable (path_conv &pc) +{ + return _unlink_nt (pc, true); +} + extern "C" int unlink (const char *ourname) { |