Hi Ben, On Jan 20 17:10, Ben Wijen wrote: > Implement wincap.has_posix_unlink_semantics_with_ignore_readonly and when set > skip setting/clearing of READONLY attribute and instead use > FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE > --- > winsup/cygwin/ntdll.h | 3 ++- > winsup/cygwin/syscalls.cc | 14 +++++----- > winsup/cygwin/wincap.cc | 11 ++++++++ > winsup/cygwin/wincap.h | 56 ++++++++++++++++++++------------------- > 4 files changed, 49 insertions(+), 35 deletions(-) > > diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h > index d4f6aaf45..7eee383dd 100644 > --- a/winsup/cygwin/ntdll.h > +++ b/winsup/cygwin/ntdll.h > @@ -497,7 +497,8 @@ enum { > FILE_DISPOSITION_DELETE = 0x01, > FILE_DISPOSITION_POSIX_SEMANTICS = 0x02, > FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK = 0x04, > - FILE_DISPOSITION_ON_CLOSE = 0x08 > + FILE_DISPOSITION_ON_CLOSE = 0x08, > + FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE = 0x10, > }; > > enum > diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc > index 4742c6653..2e50ad7d5 100644 > --- a/winsup/cygwin/syscalls.cc > +++ b/winsup/cygwin/syscalls.cc > @@ -709,14 +709,11 @@ _unlink_nt (path_conv &pc, bool shareable) > flags);
A few lines above, FILE_WRITE_ATTRIBUTES is added to the access mask, if the file is R/O. This, too, depends on wincap.has_posix_unlink_semantics_with_ignore_readonly(). > if (!NT_SUCCESS (status)) > goto out; > - /* Why didn't the devs add a FILE_DELETE_IGNORE_READONLY_ATTRIBUTE > - flag just like they did with FILE_LINK_IGNORE_READONLY_ATTRIBUTE > - and FILE_LINK_IGNORE_READONLY_ATTRIBUTE??? > - > - POSIX unlink semantics are nice, but they still fail if the file > + /* POSIX unlink semantics are nice, but they still fail if the file > has the R/O attribute set. Removing the file is very much a safe > bet afterwards, so, no transaction. */ This comment should contain a short comment "W10 1809+, blah blah", analogue to the comment in line 698 in terms of 1709+ ("++"? Oops, fix typo...). > - if (pc.file_attributes () & FILE_ATTRIBUTE_READONLY) > + if (!wincap.has_posix_unlink_semantics_with_ignore_readonly () > + && (pc.file_attributes () & FILE_ATTRIBUTE_READONLY)) I'd invert the test order here. On 1809+ systems, the majority of systems these days, the first test is always true, but it's always checked, even if the file is not R/O. First checking for R/O would reduce the hits on the "with_ignore_readonly" check. > { > status = NtSetAttributesFile (fh, pc.file_attributes () > & ~FILE_ATTRIBUTE_READONLY); > @@ -727,10 +724,13 @@ _unlink_nt (path_conv &pc, bool shareable) > } > } > fdie.Flags = FILE_DISPOSITION_DELETE | > FILE_DISPOSITION_POSIX_SEMANTICS; > + if(wincap.has_posix_unlink_semantics_with_ignore_readonly ()) ^^^ space > + fdie.Flags |= FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE; ^^^^ indentation 2, not 4. > status = NtSetInformationFile (fh, &io, &fdie, sizeof fdie, > FileDispositionInformationEx); > /* Restore R/O attribute in case we have multiple hardlinks. */ > - if (pc.file_attributes () & FILE_ATTRIBUTE_READONLY) > + if (!wincap.has_posix_unlink_semantics_with_ignore_readonly () > + && (pc.file_attributes () & FILE_ATTRIBUTE_READONLY)) Same here. Actually, on second thought, what about introducing another bool at the start of the posix handling, along the lines of const bool needs_ro_handling = (pc.file_attributes () & FILE_ATTRIBUTE_READONLY) && !wincap.has_posix_unlink_semantics_with_ignore_readonly (); and then check for needs_ro_handling throughout? Thanks, Corinna