From 0339a726da6bbfbbebd4f8aeae8617ed0dbf3b53 Mon Sep 17 00:00:00 2001 From: cvs2svn <> Date: Fri, 10 Aug 2012 09:37:39 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'cygwin- 1_7_15-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-05-09 07:32:48 UTC Yaakov Selkowitz ' * new-features.sgml (ov-new1.7.15): Fix XML syntax.': COPYING3 COPYING3.LIB ChangeLog MAINTAINERS compile config.rpath config/ChangeLog config/mh-darwin config/mh-interix config/mh-ppc-aix config/mt-alphaieee config/mt-sde config/picflag.m4 config/stdint.m4 config/tcl.m4 configure configure.ac include/ChangeLog include/dis-asm.h include/dwarf2.def include/dwarf2.h include/elf/ChangeLog include/elf/avr.h include/elf/common.h include/elf/m68hc11.h include/elf/ppc.h include/elf/s390.h include/filenames.h include/gdb/ChangeLog include/gdb/callback.h include/gdb/signals.def include/gdb/signals.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/avr.h include/opcode/m68hc11.h include/opcode/mips.h include/opcode/ppc.h include/opcode/xgate.h include/plugin-api.h ltgcc.m4 ltoptions.m4 ltversion.m4 lt~obsolete.m4 newlib/ChangeLog newlib/doc/Makefile.am newlib/doc/Makefile.in newlib/libc/include/stdio.h newlib/libc/include/string.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/types.h newlib/libc/include/sys/unistd.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/cr16/sys/asm.h newlib/libc/machine/epiphany/Makefile.am newlib/libc/machine/epiphany/Makefile.in newlib/libc/machine/epiphany/aclocal.m4 newlib/libc/machine/epiphany/configure newlib/libc/machine/epiphany/configure.in newlib/libc/machine/epiphany/machine/stdlib.h newlib/libc/machine/epiphany/setjmp.S 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/telldir.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/search/hcreate_r.c newlib/libc/stdio/asiprintf.c newlib/libc/stdio/asprintf.c newlib/libc/stdio/clearerr.c newlib/libc/stdio/fclose.c newlib/libc/stdio/fdopen.c newlib/libc/stdio/feof.c newlib/libc/stdio/ferror.c newlib/libc/stdio/fflush.c newlib/libc/stdio/fgetc.c newlib/libc/stdio/fgets.c newlib/libc/stdio/fgetwc.c newlib/libc/stdio/fgetws.c newlib/libc/stdio/fileno.c newlib/libc/stdio/findfp.c newlib/libc/stdio/fmemopen.c newlib/libc/stdio/fopen.c newlib/libc/stdio/fopencookie.c newlib/libc/stdio/fpurge.c newlib/libc/stdio/fputc.c newlib/libc/stdio/fputs.c newlib/libc/stdio/fputwc.c newlib/libc/stdio/fputws.c newlib/libc/stdio/fread.c newlib/libc/stdio/freopen.c newlib/libc/stdio/fseek.c newlib/libc/stdio/ftell.c newlib/libc/stdio/funopen.c newlib/libc/stdio/fwide.c newlib/libc/stdio/fwrite.c newlib/libc/stdio/getc.c newlib/libc/stdio/getdelim.c newlib/libc/stdio/gets.c newlib/libc/stdio/local.h newlib/libc/stdio/mktemp.c newlib/libc/stdio/open_memstream.c newlib/libc/stdio/putc.c newlib/libc/stdio/setvbuf.c newlib/libc/stdio/ungetc.c newlib/libc/stdio/ungetwc.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/stdio/vfwscanf.c newlib/libc/stdio64/fdopen64.c newlib/libc/stdio64/fopen64.c newlib/libc/stdio64/freopen64.c newlib/libc/stdio64/fseeko64.c newlib/libc/stdio64/ftello64.c newlib/libc/stdlib/mbtowc_r.c newlib/libc/stdlib/mprec.h newlib/libc/stdlib/wctomb_r.c newlib/libc/string/Makefile.am newlib/libc/string/Makefile.in newlib/libc/string/strcasestr.c newlib/libc/sys/epiphany/Makefile.am newlib/libc/sys/epiphany/Makefile.in newlib/libc/sys/epiphany/aclocal.m4 newlib/libc/sys/epiphany/configure newlib/libc/sys/epiphany/configure.in newlib/libc/sys/epiphany/e_printf.c newlib/libc/sys/rtems/crt0.c newlib/libc/sys/rtems/machine/_types.h 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/cygserver/ChangeLog winsup/cygserver/woutsup.h winsup/cygwin/ChangeLog winsup/cygwin/DevNotes winsup/cygwin/Makefile.in winsup/cygwin/advapi32.cc winsup/cygwin/child_info.h winsup/cygwin/configure.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/cygwin.din winsup/cygwin/cygwin.sc winsup/cygwin/dcrt0.cc winsup/cygwin/devices.cc winsup/cygwin/devices.in winsup/cygwin/dll_init.cc winsup/cygwin/dtable.cc winsup/cygwin/dtable.h winsup/cygwin/exceptions.cc winsup/cygwin/external.cc winsup/cygwin/fhandler.cc winsup/cygwin/fhandler.h winsup/cygwin/fhandler_clipboard.cc winsup/cygwin/fhandler_console.cc winsup/cygwin/fhandler_disk_file.cc winsup/cygwin/fhandler_dsp.cc winsup/cygwin/fhandler_fifo.cc winsup/cygwin/fhandler_mem.cc winsup/cygwin/fhandler_procnet.cc winsup/cygwin/fhandler_registry.cc winsup/cygwin/fhandler_serial.cc winsup/cygwin/fhandler_socket.cc winsup/cygwin/fhandler_tape.cc winsup/cygwin/fhandler_termios.cc winsup/cygwin/fhandler_tty.cc winsup/cygwin/fhandler_virtual.cc winsup/cygwin/fhandler_windows.cc winsup/cygwin/flock.cc winsup/cygwin/gendef winsup/cygwin/gentls_offsets winsup/cygwin/globals.cc winsup/cygwin/heap.cc winsup/cygwin/hookapi.cc winsup/cygwin/include/cygwin/if.h winsup/cygwin/include/cygwin/in.h winsup/cygwin/include/cygwin/socket.h winsup/cygwin/include/cygwin/version.h winsup/cygwin/include/elf.h winsup/cygwin/include/inttypes.h winsup/cygwin/include/mntent.h winsup/cygwin/include/netdb.h winsup/cygwin/include/stdint.h winsup/cygwin/include/sys/elf32.h winsup/cygwin/include/sys/elf64.h winsup/cygwin/include/sys/elf_common.h winsup/cygwin/include/sys/elf_generic.h winsup/cygwin/include/sys/wait.h winsup/cygwin/kernel32.cc winsup/cygwin/lib/_cygwin_crt0_common.cc winsup/cygwin/lib/crt0.h winsup/cygwin/libc/inet_addr.c winsup/cygwin/libc/inet_network.c winsup/cygwin/libc/minires-os-if.c winsup/cygwin/libc/minires.h winsup/cygwin/libc/rcmd.cc winsup/cygwin/miscfuncs.cc winsup/cygwin/miscfuncs.h winsup/cygwin/mkvers.sh winsup/cygwin/mount.cc winsup/cygwin/mount.h winsup/cygwin/net.cc winsup/cygwin/ntdll.h winsup/cygwin/passwd.cc winsup/cygwin/path.cc winsup/cygwin/path.h winsup/cygwin/pinfo.cc winsup/cygwin/pipe.cc winsup/cygwin/poll.cc winsup/cygwin/posix.sgml winsup/cygwin/posix_ipc.cc winsup/cygwin/pseudo-reloc.cc winsup/cygwin/regex/regcomp.c winsup/cygwin/registry.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/sched.cc winsup/cygwin/sec_helper.cc winsup/cygwin/security.cc winsup/cygwin/security.h winsup/cygwin/select.cc winsup/cygwin/select.h 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/strace.cc winsup/cygwin/strfuncs.cc winsup/cygwin/syscalls.cc winsup/cygwin/syslog.cc winsup/cygwin/thread.cc winsup/cygwin/thread.h winsup/cygwin/tlsoffsets.h winsup/cygwin/wait.cc winsup/cygwin/winbase.h winsup/cygwin/wincap.cc winsup/cygwin/winlean.h winsup/cygwin/winsup.h winsup/doc/ChangeLog winsup/doc/faq-programming.xml winsup/doc/faq-using.xml winsup/doc/new-features.sgml winsup/doc/pathnames.sgml winsup/doc/setup-net.sgml winsup/doc/using.sgml winsup/lsaauth/ChangeLog winsup/lsaauth/Makefile.in winsup/lsaauth/cyglsa.c winsup/lsaauth/cyglsa64.dll winsup/lsaauth/make-64bit-version-with-mingw-w64.sh 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/utils/ChangeLog winsup/utils/Makefile.in winsup/utils/bloda.cc winsup/utils/cygcheck.cc winsup/utils/cygpath.cc winsup/utils/dump_setup.cc winsup/utils/dumper.cc winsup/utils/locale.cc winsup/utils/ps.cc winsup/utils/regtool.cc winsup/utils/strace.cc 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/winsock.h winsup/w32api/include/winsock2.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: config/asmcfi.m4 config/math.m4 config/mmap.m4 config/weakref.m4 include/gdb/gdb-index.h include/leb128.h newlib/libc/string/memrchr.c winsup/cygwin/cygwait.cc winsup/cygwin/cygwait.h winsup/cygwin/include/machine/elf.h winsup/cygwin/include/sys/elf.h winsup/mingw/mingwex/membarrier.c winsup/w32api/include/sdkddkver.h --- winsup/cygwin/syscalls.cc | 183 ++++++++++++++-------------------------------- 1 file changed, 56 insertions(+), 127 deletions(-) (limited to 'winsup/cygwin/syscalls.cc') diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 1b047aaff..9fc4a298c 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -126,18 +126,6 @@ dup (int fd) return res; } -inline int -dup_finish (int oldfd, int newfd, int flags) -{ - int res; - if ((res = cygheap->fdtab.dup3 (oldfd, newfd, flags | O_EXCL)) == newfd) - { - cygheap_fdget (newfd)->inc_refcnt (); - cygheap->fdtab.unlock (); /* dup3 exits with lock set on success */ - } - return res; -} - extern "C" int dup2 (int oldfd, int newfd) { @@ -152,8 +140,8 @@ dup2 (int oldfd, int newfd) cygheap_fdget cfd (oldfd); res = (cfd >= 0) ? oldfd : -1; } - else - res = dup_finish (oldfd, newfd, 0); + else if ((res = cygheap->fdtab.dup3 (oldfd, newfd, 0)) == newfd) + cygheap->fdtab[newfd]->refcnt (1); syscall_printf ("%R = dup2(%d, %d)", res, oldfd, newfd); return res; @@ -174,8 +162,8 @@ dup3 (int oldfd, int newfd, int flags) set_errno (cfd < 0 ? EBADF : EINVAL); res = -1; } - else - res = dup_finish (oldfd, newfd, flags); + else if ((res = cygheap->fdtab.dup3 (oldfd, newfd, flags)) == newfd) + cygheap->fdtab[newfd]->refcnt (1); syscall_printf ("%R = dup3(%d, %d, %p)", res, oldfd, newfd, flags); return res; @@ -212,12 +200,7 @@ stop_transaction (NTSTATUS status, HANDLE old_trans, HANDLE trans) } static char desktop_ini[] = - "[.ShellClassInfo]\r\n" - "CLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n"; - -static char desktop_ini_ext[] = - "LocalizedResourceName=@%SystemRoot%\\system32\\shell32.dll,-8964\r\n"; - + "[.ShellClassInfo]\r\nCLSID={645FF040-5081-101B-9F08-00AA002F954E}\r\n"; static BYTE info2[] = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -228,8 +211,7 @@ enum bin_status { dont_move, move_to_bin, - has_been_moved, - dir_not_empty + has_been_moved }; static bin_status @@ -246,9 +228,7 @@ 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 (); tmp_pathbuf tp; PBYTE infobuf = (PBYTE) tp.w_get (); @@ -273,8 +253,8 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) RtlInitEmptyUnicodeString (&recycler, recyclerbuf, sizeof recyclerbuf); if (!pc.isremote ()) { - if (wincap.has_recycle_dot_bin ()) /* NTFS and FAT since Vista, ReFS */ - RtlAppendUnicodeToString (&recycler, L"\\$RECYCLE.BIN\\"); + if (wincap.has_recycle_dot_bin ()) /* NTFS and FAT since Vista */ + RtlAppendUnicodeToString (&recycler, L"\\$Recycle.Bin\\"); else if (pc.fs_is_ntfs ()) /* NTFS up to 2K3 */ RtlAppendUnicodeToString (&recycler, L"\\RECYCLER\\"); else if (pc.fs_is_fat ()) /* FAT up to 2K3 */ @@ -311,10 +291,10 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) recycler.Length -= sizeof (WCHAR); /* Store length of recycler base dir, if it's necessary to create it. */ recycler_base_len = recycler.Length; - /* On NTFS or ReFS the recycler dir contains user specific subdirs, which - are the actual recycle bins per user. The name if this dir is the - string representation of the user SID. */ - if (fs_has_per_user_recycler) + /* On NTFS the recycler dir contains user specific subdirs, which are the + actual recycle bins per user. The name if this dir is the string + representation of the user SID. */ + if (pc.fs_is_ntfs ()) { UNICODE_STRING sid; WCHAR sidbuf[128]; @@ -341,10 +321,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,15 +338,12 @@ 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. First reopen root dir with permission to create subdirs. */ NtClose (rootdir); - InitializeObjectAttributes (&attr, &root, OBJ_CASE_INSENSITIVE, - NULL, NULL); status = NtOpenFile (&rootdir, FILE_ADD_SUBDIRECTORY, &attr, &io, FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT); if (!NT_SUCCESS (status)) @@ -380,17 +354,14 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) } /* Then check if recycler exists by opening and potentially creating it. Yes, we can really do that. Typically the recycle bin is created - by the first user actually using the bin. Pre-Vista, the permissions - are the default permissions propagated from the root directory. - Since Vista the top-level recycle dir has explicit permissions. */ + by the first user actually using the bin. The permissions are the + default permissions propagated from the root directory. */ InitializeObjectAttributes (&attr, &recycler, OBJ_CASE_INSENSITIVE, - rootdir, - wincap.has_recycle_dot_bin () - ? recycler_sd (true, true) : NULL); + rootdir, NULL); recycler.Length = recycler_base_len; status = NtCreateFile (&recyclerdir, READ_CONTROL - | (fs_has_per_user_recycler ? 0 : FILE_ADD_FILE), + | (pc.fs_is_ntfs () ? 0 : FILE_ADD_FILE), &attr, &io, NULL, FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM @@ -405,12 +376,10 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) } /* Next, if necessary, check if the recycler/SID dir exists and create it if not. */ - if (fs_has_per_user_recycler) + if (pc.fs_is_ntfs ()) { NtClose (recyclerdir); recycler.Length = recycler_user_len; - InitializeObjectAttributes (&attr, &recycler, OBJ_CASE_INSENSITIVE, - rootdir, recycler_sd (false, true)); status = NtCreateFile (&recyclerdir, READ_CONTROL | FILE_ADD_FILE, &attr, &io, NULL, FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM @@ -431,7 +400,7 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) { RtlInitUnicodeString (&fname, L"desktop.ini"); InitializeObjectAttributes (&attr, &fname, OBJ_CASE_INSENSITIVE, - recyclerdir, recycler_sd (false, false)); + recyclerdir, NULL); status = NtCreateFile (&tmp_fh, FILE_GENERIC_WRITE, &attr, &io, NULL, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, FILE_SHARE_VALID_FLAGS, FILE_CREATE, @@ -447,15 +416,6 @@ try_to_bin (path_conv &pc, HANDLE &fh, ACCESS_MASK access) if (!NT_SUCCESS (status)) debug_printf ("NtWriteFile (%S) failed, status = %p", &fname, status); - else if (wincap.has_recycle_dot_bin ()) - { - status = NtWriteFile (tmp_fh, NULL, NULL, NULL, &io, - desktop_ini_ext, - sizeof desktop_ini_ext - 1, NULL, NULL); - if (!NT_SUCCESS (status)) - debug_printf ("NtWriteFile (%S) failed, status = %p", - &fname, status); - } NtClose (tmp_fh); } if (!wincap.has_recycle_dot_bin ()) /* No INFO2 file since Vista */ @@ -483,7 +443,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 +459,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 +490,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 +657,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 +730,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 +797,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 +808,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 +851,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 +862,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 +2261,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 -- cgit v1.2.3