diff options
author | cvs2svn <> | 2012-08-10 13:37:40 +0400 |
---|---|---|
committer | cvs2svn <> | 2012-08-10 13:37:40 +0400 |
commit | 4b180996100bf96c9c4bdc53c75f1593c93f96a8 (patch) | |
tree | be34249cf6536ee82500baaa37c77f62c63958d4 /winsup/cygwin/syscalls.cc | |
parent | c0956742a74d194b9c18c7a91aa6d6010beb4cd3 (diff) |
This commit was manufactured by cvs2svn to create tag 'cygwin-cygwin-1_7_16-release
1_7_16-release'.
Sprout from cygwin-64bit-branch 2012-08-10 09:37:33 UTC cvs2svn 'This commit was manufactured by cvs2svn to create branch 'cygwin-64bit-'
Cherrypick from master 2012-07-20 09:45:34 UTC Corinna Vinschen <corinna@vinschen.de> 'Forced checkin to fix date':
compile
include/ChangeLog
include/dis-asm.h
include/elf/m68hc11.h
include/mach-o/ChangeLog
include/mach-o/codesign.h
include/mach-o/external.h
include/mach-o/loader.h
include/mach-o/reloc.h
include/mach-o/x86-64.h
include/opcode/ChangeLog
include/opcode/mips.h
ltoptions.m4
ltversion.m4
lt~obsolete.m4
newlib/ChangeLog
newlib/libc/include/stdio.h
newlib/libc/include/sys/signal.h
newlib/libc/include/sys/stat.h
newlib/libc/include/sys/time.h
newlib/libc/include/sys/times.h
newlib/libc/include/sys/wait.h
newlib/libc/locale/lmessages.c
newlib/libc/locale/lmonetary.c
newlib/libc/locale/nl_langinfo.c
newlib/libc/machine/rl78/Makefile.am
newlib/libc/machine/rl78/Makefile.in
newlib/libc/machine/rl78/aclocal.m4
newlib/libc/machine/rl78/configure
newlib/libc/machine/rl78/configure.in
newlib/libc/machine/rl78/setjmp.S
newlib/libc/posix/collate.c
newlib/libc/posix/engine.c
newlib/libc/posix/glob.c
newlib/libc/posix/popen.c
newlib/libc/posix/readdir.c
newlib/libc/posix/regcomp.c
newlib/libc/posix/wordexp.c
newlib/libc/reent/mkdirr.c
newlib/libc/reent/renamer.c
newlib/libc/search/hash.c
newlib/libc/search/hash_bigkey.c
newlib/libc/search/hash_page.c
newlib/libc/stdio/asiprintf.c
newlib/libc/stdio/asprintf.c
newlib/libc/stdio/freopen.c
newlib/libc/stdio/mktemp.c
newlib/libc/stdio/vasiprintf.c
newlib/libc/stdio/vasprintf.c
newlib/libc/stdio/vfprintf.c
newlib/libc/stdio/vfscanf.c
newlib/libc/stdio/vfwprintf.c
newlib/libc/stdlib/mbtowc_r.c
newlib/libc/stdlib/mprec.h
newlib/libc/stdlib/wctomb_r.c
newlib/libc/string/strcasestr.c
newlib/libc/sys/sysnecv850/crt0.S
newlib/libc/time/strptime.c
newlib/libm/common/sf_round.c
newlib/libm/math/e_atan2.c
newlib/libm/math/e_exp.c
newlib/libm/math/e_pow.c
newlib/libm/math/e_rem_pio2.c
newlib/libm/math/ef_exp.c
newlib/libm/math/ef_pow.c
newlib/libm/math/er_lgamma.c
newlib/libm/math/erf_lgamma.c
newlib/testsuite/newlib.stdio/stdio.exp
newlib/testsuite/newlib.stdio/swprintf.c
winsup/ChangeLog
winsup/Makefile.common
winsup/cygwin/ChangeLog
winsup/cygwin/DevNotes
winsup/cygwin/Makefile.in
winsup/cygwin/cygheap.cc
winsup/cygwin/cygheap.h
winsup/cygwin/cygserver_ipc.h
winsup/cygwin/cygthread.cc
winsup/cygwin/cygtls.cc
winsup/cygwin/cygtls.h
winsup/cygwin/cygwait.cc
winsup/cygwin/cygwait.h
winsup/cygwin/dcrt0.cc
winsup/cygwin/exceptions.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/fhandler_tape.cc
winsup/cygwin/fhandler_termios.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/fhandler_windows.cc
winsup/cygwin/flock.cc
winsup/cygwin/gendef
winsup/cygwin/gentls_offsets
winsup/cygwin/include/cygwin/socket.h
winsup/cygwin/include/cygwin/version.h
winsup/cygwin/include/inttypes.h
winsup/cygwin/include/stdint.h
winsup/cygwin/include/sys/wait.h
winsup/cygwin/lib/crt0.h
winsup/cygwin/ntdll.h
winsup/cygwin/path.cc
winsup/cygwin/path.h
winsup/cygwin/poll.cc
winsup/cygwin/posix_ipc.cc
winsup/cygwin/release/1.7.10
winsup/cygwin/release/1.7.11
winsup/cygwin/release/1.7.12
winsup/cygwin/release/1.7.13
winsup/cygwin/release/1.7.14
winsup/cygwin/release/1.7.15
winsup/cygwin/release/1.7.16
winsup/cygwin/security.h
winsup/cygwin/select.cc
winsup/cygwin/shared.cc
winsup/cygwin/signal.cc
winsup/cygwin/sigproc.cc
winsup/cygwin/sigproc.h
winsup/cygwin/smallprint.cc
winsup/cygwin/spawn.cc
winsup/cygwin/syscalls.cc
winsup/cygwin/thread.cc
winsup/cygwin/thread.h
winsup/cygwin/tlsoffsets.h
winsup/cygwin/wait.cc
winsup/cygwin/wincap.cc
winsup/cygwin/winlean.h
winsup/cygwin/winsup.h
winsup/doc/ChangeLog
winsup/doc/faq-using.xml
winsup/mingw/ChangeLog
winsup/mingw/configure
winsup/mingw/configure.in
winsup/mingw/include/_mingw.h
winsup/mingw/include/excpt.h
winsup/mingw/include/inttypes.h
winsup/mingw/include/limits.h
winsup/mingw/include/process.h
winsup/mingw/include/stdint.h
winsup/mingw/include/stdio.h
winsup/mingw/include/stdlib.h
winsup/mingw/include/sys/param.h
winsup/mingw/include/wchar.h
winsup/mingw/mingwex/Makefile.in
winsup/mingw/mingwex/gdtoa/gd_qnan.h
winsup/mingw/mingwex/tsearch.c
winsup/w32api/ChangeLog
winsup/w32api/include/setupapi.h
winsup/w32api/include/winbase.h
winsup/w32api/include/windows.h
winsup/w32api/include/winnt.h
winsup/w32api/include/winuser.h
winsup/w32api/include/winver.h
winsup/w32api/include/wtsapi32.h
winsup/w32api/lib/Makefile.in
winsup/w32api/lib/kernel32.def
winsup/w32api/lib/wtsapi32.def
Delete:
winsup/mingw/mingwex/membarrier.c
winsup/w32api/include/sdkddkver.h
Diffstat (limited to 'winsup/cygwin/syscalls.cc')
-rw-r--r-- | winsup/cygwin/syscalls.cc | 115 |
1 files changed, 39 insertions, 76 deletions
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 1b047aaff..2077a0a3c 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -228,8 +228,7 @@ enum bin_status { dont_move, move_to_bin, - has_been_moved, - dir_not_empty + has_been_moved }; static bin_status @@ -246,7 +245,6 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) PFILE_NAME_INFORMATION pfni; PFILE_INTERNAL_INFORMATION pfii; PFILE_RENAME_INFORMATION pfri; - ULONG frisiz; FILE_DISPOSITION_INFORMATION disp = { TRUE }; bool fs_has_per_user_recycler = pc.fs_is_ntfs () || pc.fs_is_refs (); @@ -341,10 +339,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) pc.fs_flags () & FILE_UNICODE_ON_DISK ? L".\xdc63\xdc79\xdc67" : L".cyg"); pfii = (PFILE_INTERNAL_INFORMATION) infobuf; - /* Note: Modern Samba versions apparently don't like buffer sizes of more - than 65535 in some NtQueryInformationFile/NtSetInformationFile calls. - Therefore we better use exact buffer sizes from now on. */ - status = NtQueryInformationFile (fh, &io, pfii, sizeof *pfii, + status = NtQueryInformationFile (fh, &io, pfii, 65536, FileInternalInformation); if (!NT_SUCCESS (status)) { @@ -361,8 +356,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) pfri->RootDirectory = pc.isremote () ? NULL : rootdir; pfri->FileNameLength = recycler.Length; memcpy (pfri->FileName, recycler.Buffer, recycler.Length); - frisiz = sizeof *pfri + pfri->FileNameLength - sizeof (WCHAR); - status = NtSetInformationFile (fh, &io, pfri, frisiz, FileRenameInformation); + status = NtSetInformationFile (fh, &io, pfri, 65536, FileRenameInformation); if (status == STATUS_OBJECT_PATH_NOT_FOUND && !pc.isremote ()) { /* Ok, so the recycler and/or the recycler/SID directory don't exist. @@ -483,7 +477,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) } NtClose (recyclerdir); /* Shoot again. */ - status = NtSetInformationFile (fh, &io, pfri, frisiz, + status = NtSetInformationFile (fh, &io, pfri, 65536, FileRenameInformation); } if (!NT_SUCCESS (status)) @@ -499,26 +493,6 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) Otherwise the below code closes the handle to allow replacing the file. */ status = NtSetInformationFile (fh, &io, &disp, sizeof disp, FileDispositionInformation); - if (status == STATUS_DIRECTORY_NOT_EMPTY) - { - /* Uh oh! This was supposed to be avoided by the check_dir_not_empty - test in unlink_nt, but given that the test isn't atomic, this *can* - happen. Try to move the dir back ASAP. */ - pfri->RootDirectory = NULL; - pfri->FileNameLength = pc.get_nt_native_path ()->Length; - memcpy (pfri->FileName, pc.get_nt_native_path ()->Buffer, - pc.get_nt_native_path ()->Length); - frisiz = sizeof *pfri + pfri->FileNameLength - sizeof (WCHAR); - if (NT_SUCCESS (NtSetInformationFile (fh, &io, pfri, frisiz, - FileRenameInformation))) - { - /* Give notice to unlink_nt and leave immediately. This avoids - closing the handle, which might still be used if called from - the rm -r workaround code. */ - bin_stat = dir_not_empty; - goto out; - } - } /* In case of success, restore R/O attribute to accommodate hardlinks. That leaves potentially hardlinks around with the R/O bit suddenly off if setting the delete disposition failed, but please, keep in @@ -550,7 +524,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) status); goto out; } - status = NtSetInformationFile (tmp_fh, &io, pfri, frisiz, + status = NtSetInformationFile (tmp_fh, &io, pfri, 65536, FileRenameInformation); NtClose (tmp_fh); if (!NT_SUCCESS (status)) @@ -717,45 +691,46 @@ unlink_nt (path_conv &pc) 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); - /* 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 - SFU 3.5 if the NFS share has been mounted under a drive letter. It's - not generated for all files, but only for some. If it's generated once - for a file, it will be generated all the time. It looks as if wrong file - state information is stored within the NFS client which never times out. - Opening the file with FILE_SHARE_VALID_FLAGS will work, though, and it - is then possible to delete the file quite normally. */ if (status == STATUS_SHARING_VIOLATION || status == STATUS_LOCK_NOT_GRANTED) { - debug_printf ("Sharing violation when opening %S", - pc.get_nt_native_path ()); - /* We never call try_to_bin on NFS and NetApp for the follwing reasons: - - NFS implements its own mechanism to remove in-use files, which looks - quite similar to what we do in try_to_bin for remote files. + /* 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 SFU 3.5 if the NFS share has been + mounted under a drive letter. It's not generated for all files, but + only for some. If it's generated once for a file, it will be + generated all the time. It looks like wrong file state information + is stored within the NFS client, for no apparent reason, which never + times out. Opening the file with FILE_SHARE_VALID_FLAGS will work, + though, and it is then possible to delete the file quite normally. + + NFS implements its own mechanism to remove in-use files which + looks quite similar to what we do in try_to_bin for remote files. + That's why we don't call try_to_bin on NFS. Netapp filesystems don't understand the "move and delete" method at all and have all kinds of weird effects. Just setting the delete dispositon usually works fine, though. */ + debug_printf ("Sharing violation when opening %S", + pc.get_nt_native_path ()); if (!pc.fs_is_nfs () && !pc.fs_is_netapp ()) bin_stat = move_to_bin; - /* If the file is not a directory, of if we didn't set the move_to_bin - flag, just proceed with the FILE_SHARE_VALID_FLAGS set. */ - if (!pc.isdir () || bin_stat == dont_move) + if (!pc.isdir () || pc.isremote ()) status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_VALID_FLAGS, flags); else { - /* Otherwise it's getting tricky. The directory is opened in some - process, so we're supposed to move it to the recycler and mark it - for deletion. But what if the directory is not empty? The move + /* It's getting tricky. The directory is opened in some process, + so we're supposed to move it to the recycler and mark it for + deletion. But what if the directory is not empty? The move will work, but the subsequent delete will fail. So we would - have to move it back. While we do that in try_to_bin, it's bad, - because the move results in a temporary inconsistent state. - So, we test first if the directory is empty. If not, we bail - out with STATUS_DIRECTORY_NOT_EMPTY. This avoids most of the - problems. */ + have to move it back. That's bad, because the directory would + be moved around which results in a temporary inconsistent state. + So, what we do here is to test if the directory is empty. If + not, we bail out with STATUS_DIRECTORY_NOT_EMPTY. The below code + tests for at least three entries in the directory, ".", "..", + and another one. Three entries means, not empty. This doesn't + work for the root directory of a drive, but the root dir can + neither be deleted, nor moved anyway. */ status = NtOpenFile (&fh, access | FILE_LIST_DIRECTORY | SYNCHRONIZE, &attr, &io, FILE_SHARE_VALID_FLAGS, flags | FILE_SYNCHRONOUS_IO_NONALERT); @@ -789,15 +764,9 @@ unlink_nt (path_conv &pc) /* Try to move to bin if a sharing violation occured. If that worked, we're done. */ if (bin_stat == move_to_bin - && (bin_stat = try_to_bin (pc, fh, access)) >= has_been_moved) + && (bin_stat = try_to_bin (pc, fh, access)) == has_been_moved) { - if (bin_stat == has_been_moved) - status = STATUS_SUCCESS; - else - { - status = STATUS_DIRECTORY_NOT_EMPTY; - NtClose (fh); - } + status = STATUS_SUCCESS; goto out; } @@ -862,7 +831,6 @@ try_again: bin_stat = try_to_bin (pc, fh, access); } } - /* Do NOT handle bin_stat == dir_not_empty here! */ if (bin_stat == has_been_moved) status = STATUS_SUCCESS; else @@ -874,15 +842,12 @@ try_again: } } } - else if (status2 != STATUS_OBJECT_PATH_NOT_FOUND - && status2 != STATUS_OBJECT_NAME_NOT_FOUND) + else { fh = NULL; debug_printf ("Opening dir %S for check_dir_not_empty failed, " "status = %p", pc.get_nt_native_path (), status2); } - else /* Directory disappeared between NtClose and NtOpenFile. */ - status = STATUS_SUCCESS; } /* Trying to delete a hardlink to a file in use by the system in some way (for instance, font files) by setting the delete disposition fails @@ -920,10 +885,8 @@ try_again: unlinking didn't work. */ if (bin_stat == dont_move) bin_stat = try_to_bin (pc, fh, access); - if (bin_stat >= has_been_moved) - status = bin_stat == has_been_moved - ? STATUS_SUCCESS - : STATUS_DIRECTORY_NOT_EMPTY; + if (bin_stat == has_been_moved) + status = STATUS_SUCCESS; } else NtClose (fh2); @@ -933,7 +896,7 @@ try_again: { if (access & FILE_WRITE_ATTRIBUTES) { - /* Restore R/O attribute if setting the delete disposition failed. */ + /* Restore R/O attribute if setting the delete dispostion failed. */ if (!NT_SUCCESS (status)) NtSetAttributesFile (fh, pc.file_attributes ()); /* If we succeeded, restore R/O attribute to accommodate hardlinks. @@ -2332,7 +2295,7 @@ retry: { debug_printf ("status %p", status); if (status == STATUS_SHARING_VIOLATION - && cygwait (10L) != WAIT_SIGNALED) + && WaitForSingleObject (signal_arrived, 10L) != WAIT_OBJECT_0) { /* Typical BLODA problem. Some virus scanners check newly generated files and while doing that disallow DELETE access. That's really |